spring之手撸aop
上一期说到如何做到手撸IoC,讲句实话,如果理解了ioc和DI的思想,那么其实ioc并不是很难,难在如何记住它们的api。今天的话还是继续说一下如何手撸aop
aop是什么?
首先我们必须知道aop是什么?
aop(Aspect Orirented Programming)面向切面编程。通过预编译方式和运行期动态代理进行实现。其实通俗来讲就是某些方法功能单一,我不想改动源码,且这些方法需要增加的功能一致,这个时候我们就需要使用aop的方法
aop有哪两种实现方式?
1. Jdk动态代理
2. Cglib动态代理
既然是两种代理方式,那么我们知道两者必然有不同点。首先我们说一下Jdk动态代理:该动态代理的方式是对接口进行代理。而Cglib是对类进行代理。所以两种是不同的方式进行代理,而且api也是不相同
我们看下各自的源码应该如何填写
JDK
if(objects[i].getClass().getInterfaces() != null &&
objects[i].getClass().getInterfaces().length > 0){
// jdk proxy
cn.yang.proxy.jdk.JDKProxyTest proxyTest =
(cn.yang.proxy.jdk.JDKProxyTest)Proxy.newProxyInstance(
//ClassLoader loader,
jdkProxyTestImpl.getClass().getClassLoader(),
//@NotNull Class<?>[] interfaces,
jdkProxyTestImpl.getClass().getInterfaces(),
//@NotNull reflect.InvocationHandler h
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
adviceTest.beforeProxy();
Object invoke = method.invoke(jdkProxyTestImpl, args);
adviceTest.afterProxy();
return invoke;
}
}
);
proxyTest.sayHello();
Cglib
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(objects[i].getClass());
final int finalI = i;
enhancer.setCallback(new MethodInterceptor() {
public Object intercept(Object proxy, Method method, Object[] o, MethodProxy methodProxy) throws Throwable {
adviceTest.beforeProxy();
Object invoke = method.invoke( objects[finalI], args);
adviceTest.afterProxy();
return invoke;
}
});
CglibTest test = (CglibTest) enhancer.create();
因此我们可以看的出来,两者接收的类型不同,而且如果使用Jdk代理的方式,我们是不用导包的,而使用Cglib的方式,我们还需要进行导包
现在应该会有疑问了,spring如何自动判断用什么进行实现的呢???其实很简单,就是使用反射进行判断接口数量,来进行的自动实现,如果有接口,那么肯定使用JDK代理,反之就使用Cglib进行代理。