JDK动态代理
例子:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @author Pickle
* @version V1.0
* @date 2024/2/16 17:25
*/
interface Calculator {
void add();
void sub();
}
class CalculatorImp implements Calculator {
@Override
public void add() {
System.out.println("加法");
}
@Override
public void sub() {
System.out.println("减法");
}
}
//计算代理类需要实现InvocationHandler接口,并且含有被代理类的对象
class CalculatorProxy implements InvocationHandler {
private Object object;
public CalculatorProxy(Object object){
this.object = object;
}
@Override
public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
//method 与代理对象调用的方法对应
System.out.println("计算前");
method.invoke(object, objects);
System.out.println("计算后");
return null;
}
}
public class JDKDynamicProxyDemo {
public static void main(String[] args) {
//定义被代理对象
Calculator calculator = new CalculatorImp();
final Calculator proxy = (Calculator) Proxy.newProxyInstance(
calculator.getClass().getClassLoader(),
calculator.getClass().getInterfaces(),
new CalculatorProxy(calculator));
proxy.sub();
System.out.println("-----------");
proxy.add();
}
}
结果
计算前
减法
计算后
-----------
计算前
加法
计算后
总结:JDK动态代理最致命的缺点就是只能代理实现了接口的类,使用CGLIB动态代理可以解决这个问题
CGLIB动态代理
/**
* 被代理类(无需实现接口)
* @author Pickle
* @version V1.0
* @date 2024/2/16 20:17
*/
public class Calculator {
public void sub() {
System.out.println("sub");
}
public void add(){
System.out.println("add");
}
}
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
/**
* 自定义方法拦截器
* @author Pickle
* @version V1.0
* @date 2024/2/16 20:18
*/
public class MyMethodInterceptor implements MethodInterceptor{
/**
* @param o 被代理的对象
* @param method 被拦截的方法
* @param objects 方法入参
* @param methodProxy 用于调用原始方法
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("before method " + method.getName());
methodProxy.invokeSuper(o, objects);
System.out.println("after method " + method.getName());
return objects;
}
}
import net.sf.cglib.proxy.Enhancer;
/**
* 代理类工厂
* @author Pickle
* @version V1.0
* @date 2024/2/16 20:22
*/
public class CglibProxyFactory {
/**
* @param clazz 被增强类的class对象
*/
public static Object getProperty(Class<?> clazz) {
//创建动态代理增强类
final Enhancer enhancer = new Enhancer();
//设置类加载器
enhancer.setClassLoader(clazz.getClassLoader());
//设置被代理类
enhancer.setSuperclass(clazz);
//设置方法拦截器
enhancer.setCallback(new MyMethodInterceptor());
return enhancer.create();
}
}
执行
public class execute {
public static void main(String[] args) {
final Calculator aliSmsServiceProxy = (Calculator) CglibProxyFactory.getProperty(Calculator.class);
aliSmsServiceProxy.sub();
System.out.println("----------------");
aliSmsServiceProxy.add();
}
}
结果
before method sub
sub
after method sub
----------------
before method add
add
after method add
标签:System,代理,public,println,动态,method,out
From: https://www.cnblogs.com/poteitoutou/p/18017428