“你对Spring Aop 底层了解吗?请说说”

这个问题是周一中午电话面试时候被问到的问题。

我的回答,spring aop 是面向切面编程,日常使用比较在日志拦截记录使用比较多。 啊吧啊吧...

其实我的回答已经错啦。

我回顾这个问题,其实问题是aop 底层实现。

来说说Spring Aop。

1.首先我说的面向切面编程是没问题的,

2.aop底层是使用了代理模式

有两种代理模式组成了aop.

a.jdk动态代理

利用拦截器加上反射机制生成一个实现代理接口的匿名类,然后在具体方法前调用

b.cglib动态代理

利用了ASM开源包,对代理对象类的class文件加载进来,通过修改其字节码生成子类来处理

c.何时使用jdk代理,何时使用cglib代理呢?

1.如果目标对象实现了接口。默认情况是采用jdk动态代理实现aop
2.如果目标对象实现了接口,可以强制使用cglib实现aop
3.如果目标对象没有实现接口,必须采用cglib,Spring会自动在jdk动态代理和cglib之间转换

d.如何强制使用cglib实现aop?
1.添加cglib 库
2.在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true" />

e.动态代理和cglib字节码生成的区别?

1.jdk动态代理只能对实现了接口的类生成代理,而不能针对类
2.cglib 是针对类实现代理,主要是对指定类生成一个子类,覆盖其中的方法并覆盖其中方法的实现增强,但是采用的是继承,所以这个类的方法最好不要申明成final
final 修饰的类或方法是无法继承的

f.cglib比jdk快

jdk8的时候,代理效率高于cglib

g.spring如何选择jdk还是cglib代理

1.当bean实现接口时,Spring就会用jdk动态代理
2.当Bean没有实现接口时,Spring使用cglib实现
3.可以强制指定cglib,配置文件中增加配置

总结:

jdk代理不要第三方包,只要有jdk环境就可以进行代理,使用条件:
1.实现InvocationHandler
2.使用Proxy.newProxyInstance产生代理对象
3.被代理的对象必须要实现接口