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:渣渣一枚,如有不对,请指出。

posted @ 2017-11-28 11:52  十禾。  阅读(289)  评论(0编辑  收藏  举报