JDK 的动态代理:针对实现了接口的类产生代理。
CGlib 的动态代理:针对没有实现接口的类产生代理,应用的是底层的字节码增强的技术 生成当前类的子类对象

JDK动态代理实现
1. 创建接口和对应实现类

 public interface UserService {
void login();
void loginOut();
}
 //实现类
public class UserServiceImpl implements UserService {
public void login() {
System.out.println("login方法触发");
}
public void loginOut() {
System.out.println("loginOut方法触发");
}
}

2.创建动态代理类

 public class PerformHandler implements InvocationHandler {
private Object target; //目标对象
public PerformHandler(Object target){
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//本方法中的其他输出输入增强
System.out.println("方法触发了");
//执行被代理类 原方法
Object invoke = method.invoke(target, args);
System.out.println("执行完毕了");
return invoke;
}
}

测试

 @Test
public void test1(){
//测试JDK动态代理技术
UserService userService = new UserServiceImpl();
PerformHandler performHandler = new PerformHandler(userService);
userService = (UserService)
Proxy.newProxyInstance(userService.getClass().getClassLoader(),
userService.getClass().getInterfaces(),
performHandler
);
userService.login();
}

测试结果: 在调用接口方法的前后都会添加代理类的方法!

CGlib实现代理
使用JDK创建代理有一个限制,它只能为接口创建代理实例.这一点可以从Proxy的接口方法
newProxyInstance(ClassLoader loader,Class [] interfaces,InvocarionHandler h)中看的很清楚
第二个入参 interfaces就是需要代理实例实现的接口列表.
对于没有通过接口定义业务方法的类,如何动态创建代理实例呢? JDK动态代理技术显然已经黔驴技穷,CGLib
作为一个替代者,填补了这一空缺.
GCLib采用底层的字节码技术,可以为一个类创建子类,在子类中采用方法拦截的技术拦截所有父类方法的调用
并顺势织入横切逻辑.

1. 创建创建CGLib代理器

 public class CglibProxy implements MethodInterceptor {

     private Enhancer enhancer = new Enhancer();
//设置被代理对象
public Object getProxy(Class clazz){
enhancer.setSuperclass(clazz);
enhancer.setCallback(this);
return enhancer.create();
}
@Override
public Object intercept(Object obj, Method method,
Object[] objects,
MethodProxy methodProxy) throws Throwable {
System.out.println("CGLig代理之前之前");
Object invoke = methodProxy.invokeSuper(obj,objects);
System.out.println("CGLig代理之前之后");
return invoke;
} }

测试

 @Test
public void test2(){
//TODO CGlib实现
CglibProxy cglibProxy = new CglibProxy();
UserServiceImpl userService= (UserServiceImpl)
cglibProxy.getProxy(UserServiceImpl.class);
userService.login();
}

结果:

Spring的 AOP底层用到两种代理机制-LMLPHP

04-18 11:50
查看更多