切面(Aspect) :官方的抽象定义为“一个关注点的模块化,这个关注点可能会横切多个对象”。 连接点(Joinpoint) :程序执行过程中的某一行为。 通知(Advice) :“切面”对于某个“连接点”所产生的动作。 切入点(Pointcut) :匹配连接点的断言,在AOP中通知和一个切入点表达式关联。 目标对象(Target Object) :被一个或者多个切面所通知的对象。 织入(Weaving):将切面应用到目标对象从而创建一个新的代理对象的过程。 AOP代理(AOP Proxy) 在Spring AOP中有两种代理方式,JDK动态代理和CGLIB代理。
解析自定义标签<aop:aspectj-autoproxy />,会去项目下META-INF目录下找到文spring.handlers,据标签的命名空间找到对应的AopNamespaceHandler,在初始完成以后会调用init进行BeanDefinitionParser的注册,通过BeanDefinitionParse的parse方法将标签解析成AnnotationAwareAspectJAutoProxyCreator对应的BeanDefinition并注册到ParserContext。通过BeanDefinitionParserDelegate#parseCustomElement方法去实现:
public BeanDefinition parseCustomElement(Element ele, BeanDefinition containingBd) { String namespaceUri = getNamespaceURI(ele); NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri); if (handler == null) { error("Unable to locate Spring NamespaceHandler for XML schema namespace [" + namespaceUri + "]", ele); return null; } return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd)); }看一下AnnotationAwareAspectJAutoProxyCreator类的继承结构它,实现了SmartInstantiationAwareBeanPostProcessor,而SmartInstantiationAwareBeanPostProcessor继承自BeanPostProcessor。 ClassPathXmlApplicationContext在创建的过程中会调用父类AbstractApplicationContex的refresh方法,先进行BeanPostProcessor的注册,然后去注册普通的bean。部分源码:
// Register bean processors that intercept bean creation. registerBeanPostProcessors(beanFactory); // Initialize message source for this context. initMessageSource(); // Initialize event multicaster for this context. initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. onRefresh(); // Check for listener beans and register them. registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. finishBeanFactoryInitialization(beanFactory);根据上节循环依赖中讲述的在bean创建的过程有一个重要的方法getEarlyBeanReference,在这个方法中会去调用SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference去给bean生成代理对象,实现类AbstractAutoProxyCreator。
getEarlyBeanReference方法做两件事: 1、根据bean的class和name生成key,并进行标记; 2、判断bean是否需要被代理,如果需要代理则代理以后进行缓存。
public Object getEarlyBeanReference(Object bean, String beanName) throws BeansException { Object cacheKey = getCacheKey(bean.getClass(), beanName); this.earlyProxyReferences.add(cacheKey); return wrapIfNecessary(bean, beanName, cacheKey); }可能你也会纳闷,如果不调用getEarlyBeanReference方法,是不是就不会进行代理了,当然也不是,在bean初始化完成以后,还是会进入wrapIfNecessary方法进行代理的动作。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; } public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }1、在bean初始化完成以后,调用BeanPostProcessor的postProcessAfterInitialization进行后置处理; 2、AbstractAutoProxyCreator进行后置处理时,先判断该bean是否已经被处理过了或者; 3、从beanFactory遍历所有bean,找到拥有Aspect注解的类; 4、解析标记为Aspect注解的类,获取增强器; 5、对增强器进行缓存; 6、使用增强器对bean进行代理。 AnnotationAwareAspectJAutoProxyCreator在获取增强器的时候,先调用父类的方法去获取父类的增强器,然后在调用BeanFactoryAspectJAdvisorsBuilder去生成@Aspect注解点增强器。
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. advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors()); return advisors; }BeanFactoryAspectJAdvisorsBuilder通过遍历BeanFactory所有的beanName去找到拥有@Aspect注解的类,然后委托给ReflectiveAspectJAdvisorFactory去创建具体的Advisor。buildAspectJAdvisors做两件事:1、遍历beanName找到有Aspect注解的类;2缓存ReflectiveAspectJAdvisorFactory创建的增强器。
public List<Advisor> buildAspectJAdvisors() { List<String> aspectNames = null; synchronized (this) { aspectNames = this.aspectBeanNames; if (aspectNames == null) { List<Advisor> advisors = new LinkedList<Advisor>(); aspectNames = new LinkedList<String>(); String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false); for (String beanName : beanNames) { if (!isEligibleBean(beanName)) { continue; } // We must be careful not to instantiate beans eagerly as in this // case they would be cached by the Spring container but would not // have been weaved Class<?> beanType = this.beanFactory.getType(beanName); if (beanType == null) { continue; } if (this.advisorFactory.isAspect(beanType)) { aspectNames.add(beanName); AspectMetadata amd = new AspectMetadata(beanType, beanName); if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) { MetadataAwareAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName); List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory); if (this.beanFactory.isSingleton(beanName)) { this.advisorsCache.put(beanName, classAdvisors); } else { this.aspectFactoryCache.put(beanName, factory); } advisors.addAll(classAdvisors); } else { // Per target or per this. if (this.beanFactory.isSingleton(beanName)) { throw new IllegalArgumentException("Bean with name '" + beanName + "' is a singleton, but aspect instantiation model is not singleton"); } MetadataAwareAspectInstanceFactory factory = new PrototypeAspectInstanceFactory(this.beanFactory, beanName); this.aspectFactoryCache.put(beanName, factory); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } } this.aspectBeanNames = aspectNames; return advisors; } } if (aspectNames.isEmpty()) { return Collections.emptyList(); } List<Advisor> advisors = new LinkedList<Advisor>(); for (String aspectName : aspectNames) { List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName); if (cachedAdvisors != null) { advisors.addAll(cachedAdvisors); } else { MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName); advisors.addAll(this.advisorFactory.getAdvisors(factory)); } } return advisors; }ReflectiveAspectJAdvisorFactory从字面上理解就是使用反射去解析Aspect标记的类用于生成Advisor的工厂,该方法会根据条件生成三种Advisor。 InstantiationModelAwarePointcutAdvisorImpl:用于生成方法上的@Before、@Around、@AfterThrowing、@AfterReturning、@After注解的增强器。 DeclareParentsAdvisor:用于生成属性上的@DeclareParents注解的增强器。 SyntheticInstantiationAdvisor:综合的增强器,基本上不用。
注解类型advice类型@BeforeAspectJMethodBeforeAdvice@AroundAspectJAroundAdvice@AfterThrowingAspectJAfterThrowingAdvice@AfterReturningAspectJAfterReturningAdvice@AfterAspectJAfterAdvice在获取了所有Advisor以后,找到能处理bean的Advisor,并进行排序后返回。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { List<Advisor> candidateAdvisors = findCandidateAdvisors(); List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); extendAdvisors(eligibleAdvisors); if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } return eligibleAdvisors; }AbstractAutoProxyCreator根据返回的List<Advisor> 和bean去创建bean的代理,在这个过程中会使用到JDK动态代理和CGLIB动态代理技术。