Tiny-Spring源码阅读(二)、AOP部分的理解
一、什么是AOP?
AOP含义是面向切面编程,它通过类似于横切的技术,剖解开封装对象的内部,并将那些影响了多个类的公共行为封装到一个可重用模块中,把这些模块动态放入对象内部。以此来降低耦合度,AOP涉及很多名词,所以在阅读这部分源码的时候,最好还是先将AOP的原理搞清楚。推荐这位博主的文章:SpringAOP原理。
二、AOP部分的理解
(1)切点与Advice
首先,对于一个对象,要想动态的添加一些行为,第一步做的是将行为添加在哪?即找到匹配的地方,日常使用Spring的时候总是通过一个表达式找到合适的匹配位置(即:execution(* us.codecraft.tinyioc..(..)))。这在Tiny-Spring中对应的是AspectJExpressionPointcut,他通过AspectJ表达式进行匹配,它实现的接口ClassFilter:表示与类进行匹配,MethodMatcher表示与方法匹配,PointCut:表示获取的是ClassFilter还是MethodMatcher.
String expression = "execution(* us.codecraft.tinyioc.*.*(..))";
AspectJExpressionPointcut aspectJExpressionPointcut = new AspectJExpressionPointcut();
aspectJExpressionPointcut.setExpression(expression);
boolean matches = aspectJExpressionPointcut.getClassFilter().matches(HelloWorldService.class);
Assert.assertTrue(matches);
找到了匹配的位置,接下来考虑在这个位置需要添加什么操作,即Advice,这对应的是Advisor接口,它用于获取advice。
public interface Advisor {
Advice getAdvice();
}
然后,是将advice与匹配位置整合起来,对应的是PointcutAdvisor接口,用于获取切点以及advice。它的一个实现类是AspectJExpressionPointcutAdvisor,表示通过Aspecj方式进行匹配。
(2)使用动态代理添加功能
将advice动态添加到匹配对象的匹配方法上去,生成新的对象,即获取动态代理对象。对应于AopProxy接口。
public interface AopProxy {
Object getProxy();
}
它的抽象类AbstractAopProxy有一个AdvisedSupport:用于保存被代理的对象,代理对象上执行的操作(advice),匹配方法的信息。
具体的动态代理通过Jdk动态代理实现以及Cglib动态代理实现,它们都继承自AbstractAopProxy。由于有两种实现方式,所以设置了一个ProxyFactory工厂用于获取不同代理的实现。到此,我们就可以手工去获取一个代理对象了。(以下是通过JDK方式获取)
UserService userService=new UserServiceImpl();
TargerSource targerSource=new TargerSource(userService,UserServiceImpl.class,UserService.class);
AdvisedSupport advisedSupport=new AdvisedSupport();
advisedSupport.setTargerSource(targerSource);
advisedSupport.setMethodInterceptor(new TimeMethodInterceptor());
JdkDynamicAopProxy jdkDynamicAopProxy=new JdkDynamicAopProxy(advisedSupport);
UserService userService1= (UserService) jdkDynamicAopProxy.getProxy();
userService1.show();
(3)将动态代理与切点整合
对应于AspectJExpressionPointCutCreator,先不考虑它实现的接口,只看它的方法实现。
for (AspectJExpressionPointCutAdvisor aspectJExpressionPointCutAdvisor:list) {
if (aspectJExpressionPointCutAdvisor.getPointCut().getClassFilter().match(bean.getClass())){
TargerSource targerSource=new TargerSource(bean,bean.getClass(),
bean.getClass().getInterfaces());
ProxyFactory proxyFactory=new ProxyFactory();
proxyFactory.setMethodInterceptor((MethodInterceptor) aspectJExpressionPointCutAdvisor.getAdvice());
proxyFactory.setMethodFilter(aspectJExpressionPointCutAdvisor.getPointCut().getMethodFilter());
proxyFactory.setTargerSource(targerSource);
return proxyFactory.getProxy();
}
}
表示进行类匹配,匹配成功后将对象的信息以及Advice(这里是MethodInterceptor,它实现了Advice接口)与方法匹配信息给代理工厂,由代理工厂匹配方法并生成代理对象。
(4)整合到Beanfactory中去
AspectJAwareAdvisorAutoProxyCreator实现的接口BeanPostProcessor,在工厂获得对象的时候,会优先调用这个接口的实现类。并且它实现了BeanFactoryAware接口:
public interface BeanFactoryAware {
void setBeanFactory(BeanFactory beanFactory) throws Exception;
}
表示它可以获得对于工厂容器的管理,以此为在容器中的对象动态添加功能!
三、总结
对于AOP部分,涉及到了AspectJ,aopalliance,JDK动态代理Cglib动态代理,当感觉有些地方读不懂的时候,或许是你这几个方面的知识储备不足。运用的设计模式有工厂模式、动态代理模式、模板模式。
ps:渣渣一枚,如有不对,请指出。