• Home
  • Articles
    • 日志
    • 妍小言
    • 舒小书
    • 浩然说
    • 生活日记
  • All Tags

Spring AOP

21 Nov 2018

Reading time ~1 minute

AOP的核心组件

AOP的实现依赖两个核心组件,AdvisorAutoProxyCreator和Advisor

  • Advisor:包含了切面,切入点以及切入点扩展方式(前置,后置,环绕等)
  • AdvisorAutoProxyCreator:bean的aop代理生成器

AOP的配置方式

  1. 通过xml进行配置
     <aop:config>
         <aop:aspect id="print" ref="testAspect">
             <aop:pointcut id="addAllMethod" expression="execution(* org.eddy.rest.aop.TestService.*(..))" />
             <aop:before method="print" pointcut-ref="addAllMethod"/>
             <aop:around method="aroundPrint" pointcut-ref="addAllMethod"/>
         </aop:aspect>
     </aop:config>
    
  2. 通过注解进行配置
    @Aspect
    public class AnnAspect {
    
     @Pointcut("execution(* org.eddy.rest.aop.TService.*(..))")
     public void t(){}
    
     @Around("t()")
     public Object check(ProceedingJoinPoint point) throws Throwable {
         System.out.println("today");
         return point.proceed();
     }
    }
    

AOP XML实现

AOP的XML实现,主要是基于spring的xml扩展来实现的,打开spring-aop包,可以看到META-INF文件夹下的spring.schemas和spring.handlers,其中的spring.handlers就是对AOP的XML进行的解析。 对于其中核心的config节点解析类ConfigBeanDefinitionParser,首先会尝试通过registry注册AspectJAwareAdvisorAutoProxyCreator,然后则是解析xml配置。 最终,会将其封装成AspectJPointcutAdvisor并注册。

AspectJAwareAdvisorAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,调用postProcessBeforeInstantiation方法尝试得到bean的实例。

尝试生成动态代理的实例,首先通过调用findCandidateAdvisors方法来获取所有Advisor bean,然后通过findAdvisorsThatCanApply方法和AopUtils#findAdvisorsThatCanApply进行匹配,我们一般是通过Pointcut进行过滤,还有一种方式是通过IntroductionAdvisor进行过滤,只不过我并没有用过。

最终,如果获取到匹配的Advisor,则对其进行排序,和调用字节码依赖生成动态代理实例。

AOP注解实现

注解实现和XML实现基本逻辑大致相同,但也有几点不一样,

  1. AdvisorAutoProxyCreator注册方式,是通过EnableAspectJAutoProxy注解来import的,注册的是AnnotationAwareAspectJAutoProxyCreator
  2. Advisor并不是在初始化的时候注册到BeanFactory中,而是AnnotationAwareAspectJAutoProxyCreator重写了findCandidateAdvisors方法,在尝试生成实例时,通过aspectJAdvisorsBuilder解析生成所有的Advisor,并且和xml实现不同,生成的advisor不会注册到beanFactory中。
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}
	

后面的流程则和xml实现大同小异,获取匹配的Advisor,通过字节码工具生成动态代理实例。



aop