java 中jdk动态代理和CGLIB动态代理
jdk的动态代理是需要目标接口的,而spring提供的cglib代理是不需要目标接口的。
1、jdk动态代理实践过程
定义接口
public interface Person {
public void rentHouse();
public void rentHouse(String name);
}
定义接口实现类
public class Renter implements Person{
@Override
public void rentHouse() {
System.out.println("租房");
}
@Override
public void rentHouse(String name) {
System.out.println("租房"+name);
}
}
定义代理类行为(类似于spring中aop的各种通知)
public class RenterInvocationHandler<T> implements InvocationHandler {
// 被代理类,从构造方法传入
private T target;
public RenterInvocationHandler(T target) {
this.target = target;
}
/**
* @param proxy 代表动态代理对象
* @param method 代表正在执行的方法
* @param args 代表调用目标方法时传入的实参
* @return
* @throws Throwable
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("租客和中介交流");
// 调用
Object result = method.invoke(target, args);
System.out.println("租房结束");
return result;
}
}
代理测试
public static void main(String[] args) {
// 被代理类
Person renter = new Renter();
RenterInvocationHandler<Person> renterInvocationHandler = new RenterInvocationHandler<>(renter);
// 传入类加载器,代理类需要实现的接口,handler
Person renterProxy = (Person)Proxy.newProxyInstance(Person.class.getClassLoader(),new Class<?>[]{Person.class},renterInvocationHandler);
renterProxy.rentHouse();
System.out.println();
renterProxy.rentHouse("越美国际");
}
打印结果
租客和中介交流
租房
租房结束
租客和中介交流
租房越美国际
租房结束
2、CGLIB动态代理实践过程
创建被代理类
public class Renter2 {
public void rentHouse() {
System.out.println("租房");
}
public void rentHouse(String name) {
System.out.println("租房"+name);
}
}
创建代理工厂
/**
* 该类用于生成目标类的代理对象,并且指定增强的内容,是通过重写intercept拦截方法
* @param <T>
*/
public class ProxyFactory<T> implements MethodInterceptor {
// cglib工具类
private Enhancer en = new Enhancer();
// 被代理对象
private T target;
public ProxyFactory(T target) {
this.target = target;
}
/**
* 返回代理类 proxy
* @param clazz
* @return
*/
public T getProxyInstance(Class<?> clazz){
// 父类
en.setSuperclass(clazz);
// 回调类方法所在类
en.setCallback(this);
return (T)en.create();
}
/**
* 拦截方法,增强类
* @param obj
* @param method 被代理类的method
* @param args 方法参数
* @param methodProxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
System.out.println("中介和租客交流");
Object result = method.invoke(target,args);
System.out.println("租房结束");
return result;
}
/**
* 测试过程
* @param args
*/
public static void main(String[] args) {
ProxyFactory<Renter2> renter2ProxyFactory = new ProxyFactory<>(new Renter2());
Renter2 proxyInstance = renter2ProxyFactory.getProxyInstance(Renter2.class);
proxyInstance.rentHouse();
System.out.println();
proxyInstance.rentHouse("越美国际");
}
}