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

Posted Sue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring的 AOP底层用到两种代理机制相关的知识,希望对你有一定的参考价值。

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

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

1 public interface UserService {
2 void login();
3 void loginOut();
4 }
1 //实现类
2 public class UserServiceImpl implements UserService {
3 public void login() {
4 System.out.println("login方法触发");
5 }
6 public void loginOut() {
7 System.out.println("loginOut方法触发");
8 }
9 }

2.创建动态代理类

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

测试

 1 @Test
 2 public void test1(){
 3 //测试JDK动态代理技术
 4 UserService userService = new UserServiceImpl();
 5 PerformHandler performHandler = new PerformHandler(userService);
 6 userService = (UserService)
 7 Proxy.newProxyInstance(userService.getClass().getClassLoader(),
 8 userService.getClass().getInterfaces(),
 9 performHandler
10 );
11 userService.login();
12 }

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

 

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

1. 创建创建CGLib代理器

 1 public class CglibProxy implements MethodInterceptor {
 2 
 3     private Enhancer enhancer = new Enhancer();
 4     //设置被代理对象
 5     public Object getProxy(Class clazz){
 6     enhancer.setSuperclass(clazz);
 7     enhancer.setCallback(this);
 8     return enhancer.create();
 9     }
10     @Override
11     public Object intercept(Object obj, Method method,
12             Object[] objects,
13             MethodProxy methodProxy) throws Throwable {
14         System.out.println("CGLig代理之前之前");
15         Object invoke = methodProxy.invokeSuper(obj,objects);
16         System.out.println("CGLig代理之前之后");
17         return invoke;
18     }
19 
20 }

测试

1 @Test
2 public void test2(){
3 //TODO CGlib实现
4 CglibProxy cglibProxy = new CglibProxy();
5 UserServiceImpl userService= (UserServiceImpl)
6 cglibProxy.getProxy(UserServiceImpl.class);
7 userService.login();
8 }

结果:

 

以上是关于Spring的 AOP底层用到两种代理机制的主要内容,如果未能解决你的问题,请参考以下文章

Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

Spring5学习笔记 — “Spring AOP底层原理(动态代理)”

Spring_AOP的实现机制-动态代理

Spring AOP底层原理

Spring-AOP

spring-AOP原理