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;
}
@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);
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);
}
}
创建代理工厂
public class ProxyFactory<T> implements MethodInterceptor {
private Enhancer en = new Enhancer();
private T target;
public ProxyFactory(T target) {
this.target = target;
}
public T getProxyInstance(Class<?> clazz){
en.setSuperclass(clazz);
en.setCallback(this);
return (T)en.create();
}
@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;
}
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("越美国际");
}
}