Spring命名空间之AOP

Spring加载时,会使用ClassLoader去查找所有能找到的”META-INF/spring.handlers”文件,并存放在handlerMappings中(DefaultNamespaceHandlerResolver在干这事),遇到除beans外的Namespace,就会去这里查找对应的解析器,如果不存在就报错,存在就使用相应的解析器进行解析。

<aop>是由AopNamespaceHandler来进行解析的。

AspectJAutoProxyBeanDefinitionParser会注册3个类来处理解析任务,分别对应为:

“config”, new ConfigBeanDefinitionParser();

“aspectj-autoproxy”, new AspectJAutoProxyBeanDefinitionParser();

“scoped-proxy”, new ScopedProxyBeanDefinitionDecorator();

要使用aop命名空间,需要在spring的xml中加入:

xmlns:aop="http://www.springframework.org/schema/aop"  
  
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-xsd"

这样便可以在该xml中使用<aop …/>了。

<aop:aspectj-autoproxy/>

使用该配置后,AspectJAutoProxyBeanDefinitionParser会注册AnnotationAwareAspectJAutoProxyCreator到Spring管理的bean中。由于AnnotationAwareAspectJAutoProxyCreator是BeanPostProcessor,所以在所有bean初始化完成后,都会调用该类中的postProcessAfterInitialization来进行处理。

AnnotationAwareAspectJAutoProxyCreator使用findEligibleAdvisors来查找是否有bean对应的Advisors(注册在当前beanFactory中的实现了Advisor接口的类,例如BeanFactoryTransactionAttributeSourceAdvisor),如果有,创建一个该bean的代理(AbstractAutoProxyCreator)。

如果使用了<tx:annotation-driven/>,其中的mode属性默认为proxy,解析到这里的时候,AnnotationDrivenBeanDefinitionParser会自动调用AopNamespaceUtils->AopConfigUtils,而AopConfigUtils会把AnnotationAwareAspectJAutoProxyCreator注册到beanFactory里面去,也就是相当于写了个<aop:aspectj-autoproxy/>的标签。

如果不知道程序应该使用Spring-AOP还是AspectJ,这儿有较好的描述:

http://static.springsource.org/spring/docs/3.1.x/spring-framework-reference/html/aop.html#aop-choosing

Spring-AOP默认使用JDKProxy来代理实现了任何接口的类,如果没有实现任何接口,则使用Cglib2AopProxy来创建代理,对原类的方法调用时,会根据代理类设置的Callback[]进行相应处理。

Spring-AOP默认设置的Callback有

DynamicAdvisedInterceptor(拦截方法调用,检查需要使用的拦截器并执行,例如TransactionInterceptor)

DynamicUnadvisedInterceptor/StaticUnadvisedInterceptor

StaticDispatcher

AdvisedDispatcher(不知道拿来干嘛的)

EqualsInterceptor

HashCodeInterceptor

SerializableNoOp(貌似没啥用?)

发表评论

电子邮件地址不会被公开。 必填项已用*标注