在Spring AOP工作机制进一步理解(上篇)中,通过源码,分析了<aop:config>配置下的Spring AOP工作机制,本文在总结上篇的基础上,分析<aop:aspectj-autoproxy>配置下的工作机制。
<aop:aspectj-autoproxy>
Spring xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
<!-- 用户业务逻辑bean -->
<bean id="userAction" class="org.test.aop.UserAction"/>
<!-- 扫描日志切面bean -->
<context:component-scan base-package="org.test.aop"/>
<!-- 开启AOP注解方式 -->
<aop:aspectj-autoproxy/>
</beans>
解析
工作流程
Spring xml的解析过程详见《Spring ioc容器启动流程—obtainFreshBeanFactory》,这里只涉及<aop:aspectj-autoproxy>的解析工作。AopNamespaceHandler会委托AspectJAutoProxyBeanDefinitionParser来进行解析工作,详细流程如下:
相关源码
/** AopConfigUtils.java */
// 注册AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition
// 其中cls的值为AnnotationAwareAspectJAutoProxyCreator.class
private static BeanDefinition registerOrEscalateApcAsRequired(Class cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
// 判断是否已注册AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition
// 其在beanFactory中对应的key为"org.springframework.aop.config.internalAutoProxyCreator"
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
// 创建且注册AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
/** AopNamespaceUtils.java */
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
// 获取<aop:aspectj-autoproxy/>的proxy-target-class属性值
if (proxyTargetClass) {
// 设置AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition的proxyTargetClass属性为true
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
// 获取<aop:aspectj-autoproxy/>的expose-proxy属性值
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
// 设置AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition的exposeProxy属性为true
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
/** AopConfigUtils.java */
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
/** AopNamespaceUtils.java */
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
BeanComponentDefinition componentDefinition =
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
parserContext.registerComponent(componentDefinition);
}
}
/** AspectJAutoProxyBeanDefinitionParser.java */
private void extendBeanDefinition(Element element, ParserContext parserContext) {
BeanDefinition beanDef =
parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
if (element.hasChildNodes()) {
addIncludePatterns(element, parserContext, beanDef);
}
}
生成代理对象
在<aop:aspectj-autoproxy/>解析过程中,主要工作就是注册AnnotationAwareAspectJAutoProxyCreator RootBeanDefinition。
AnnotationAwareAspectJAutoProxyCreator对象实例化
与<aop:config>方式一样。
InstantiationModelAwarePointcutAdvisorImpl对象实例化
<aop:aspectj-autoproxy/>配置下所有@Aspect中Advice注解最终都会实例为InstantiationModelAwarePointcutAdvisorImpl对象,以进行AOP拦截。与<aop:config>方式一样,在生成业务userAction代理对象过程中,InstantiationModelAwarePointcutAdvisorImpl的实例化发生在resolveBeforeInstantiation环节,与<aop:config>方式不同的是,AnnotationAwareAspectJAutoProxyCreator覆盖了AspectJAwareAdvisorAutoProxyCreator的findCandidateAdvisors方法,自行实例化注解的PointcutAdvisor。下面解析只涉及AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors,其他过程忽略。
AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors基本流程
相关源码
/** AnnotationAwareAspectJAutoProxyCreator.java */
// <aop:aspectj-autoproxy/>注解方式下的PointcutAdvisor即InstantiationModelAwarePointcutAdvisorImpl对象实例化
protected List<Advisor> findCandidateAdvisors() {
// 实例化<aop:config>的AspectJPointcutAdvisor
List<Advisor> advisors = super.findCandidateAdvisors();
// 实例化<aop:aspectj-autoproxy/>的InstantiationModelAwarePointcutAdvisorImpl
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
/** BeanFactoryAspectJAdvisorsBuilder.java */
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>();
// 获取beanFactory及其循环上级的所有bean
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;
}
// 判断beanType及其循环super Class\interface是否带@Aspect
// 采用(clazz.getAnnotation(annotationType)!= null)判断
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);
// 获取Advisors
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
// 缓存classAdvisors
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.EMPTY_LIST;
}
// 从缓存中获取advisors
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 */
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory maaif) {
final Class<?> aspectClass = maaif.getAspectMetadata().getAspectClass();
final String aspectName = maaif.getAspectMetadata().getAspectName();
validate(aspectClass);
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
final MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(maaif);
final List<Advisor> advisors = new LinkedList<Advisor>();
for (Method method : getAdvisorMethods(aspectClass)) {
// 实例化<aop:aspectj-autoproxy/>注解方式下的PointcutAdvisor即InstantiationModelAwarePointcutAdvisorImpl
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// If it's a per target aspect, emit the dummy instantiating aspect.
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields.
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
// 获取aspectClass及其循环super Class\interface的不带@Pointcut的方法
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
final List<Method> methods = new LinkedList<Method>();
// 回调doWith
ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {
public void doWith(Method method) throws IllegalArgumentException {
// 不包括pointcuts
if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
methods.add(method);
}
}
});
// 排序
Collections.sort(methods, METHOD_COMPARATOR);
return methods;
}
/** ReflectionUtils.java */
public static void doWithMethods(Class<?> clazz, MethodCallback mc) throws IllegalArgumentException {
doWithMethods(clazz, mc, null);
}
public static void doWithMethods(Class<?> clazz, MethodCallback mc, MethodFilter mf)
throws IllegalArgumentException {
// 获取Declared Methods
Method[] methods = clazz.getDeclaredMethods();
for (Method method : methods) {
if (mf != null && !mf.matches(method)) {
continue;
}
try {
mc.doWith(method);
}
catch (IllegalAccessException ex) {
throw new IllegalStateException("Shouldn't be illegal to access method '" + method.getName()
+ "': " + ex);
}
}
if (clazz.getSuperclass() != null) {
// 循环super Class
doWithMethods(clazz.getSuperclass(), mc, mf);
}
else if (clazz.isInterface()) {
for (Class<?> superIfc : clazz.getInterfaces()) {
// 循环interface
doWithMethods(superIfc, mc, mf);
}
}
}
/** ReflectiveAspectJAdvisorFactory.java */
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aif,
int declarationOrderInAspect, String aspectName) {
validate(aif.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut ajexp =
getPointcut(candidateAdviceMethod, aif.getAspectMetadata().getAspectClass());
if (ajexp == null) {
return null;
}
// PointcutAdvisor对象实例化,<aop:aspectj-autoproxy/>注解方式下的PointcutAdvisor
return new InstantiationModelAwarePointcutAdvisorImpl(
this, ajexp, aif, candidateAdviceMethod, declarationOrderInAspect, aspectName);
}
// 获取candidateAdviceMethod的advice注解,提取Pointcut,返回AspectJExpressionPointcut
private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
AspectJExpressionPointcut ajexp =
new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class[0]);
ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
return ajexp;
}
/** AbstractAspectJAdvisorFactory.java */
protected static AspectJAnnotation findAspectJAnnotationOnMethod(Method method) {
//所有Advice注解
Class<? extends Annotation>[] classesToLookFor = new Class[] {
Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
// 循环查找匹配Advice的AspectJAnnotation
for (Class<? extends Annotation> c : classesToLookFor) {
AspectJAnnotation foundAnnotation = findAnnotation(method, c);
if (foundAnnotation != null) {
return foundAnnotation;
}
}
return null;
}
private static <A extends Annotation> AspectJAnnotation<A> findAnnotation(Method method, Class<A> toLookFor) {
A result = AnnotationUtils.findAnnotation(method, toLookFor);
if (result != null) {
// 获取到annotation则直接返回AspectJAnnotation
return new AspectJAnnotation<A>(result);
}
else {
return null;
}
}
/** AnnotationUtils.java */
public static <A extends Annotation> A findAnnotation(Method method, Class<A> annotationType) {
// 获取到annotation则直接返回
A annotation = getAnnotation(method, annotationType);
Class<?> clazz = method.getDeclaringClass();
if (annotation == null) {
// 在clazz的interface中查找带annotationType的method
annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
}
while (annotation == null) {
// 在clazz的super Class中查找带annotationType的method
clazz = clazz.getSuperclass();
if (clazz == null || clazz.equals(Object.class)) {
break;
}
try {
Method equivalentMethod = clazz.getDeclaredMethod(method.getName(), method.getParameterTypes());
annotation = getAnnotation(equivalentMethod, annotationType);
}
catch (NoSuchMethodException ex) {
// No equivalent method found
}
if (annotation == null) {
annotation = searchOnInterfaces(method, annotationType, clazz.getInterfaces());
}
}
return annotation;
}
public static <A extends Annotation> A getAnnotation(Method method, Class<A> annotationType) {
Method resolvedMethod = BridgeMethodResolver.findBridgedMethod(method);
// 利用Class.getAnnotation方法获取Annotation Class
A ann = resolvedMethod.getAnnotation(annotationType);
if (ann == null) {
for (Annotation metaAnn : resolvedMethod.getAnnotations()) {
ann = metaAnn.annotationType().getAnnotation(annotationType);
if (ann != null) {
break;
}
}
}
return ann;
}
/** InstantiationModelAwarePointcutAdvisorImpl.java */
// new InstantiationModelAwarePointcutAdvisorImpl对象
public InstantiationModelAwarePointcutAdvisorImpl(AspectJAdvisorFactory af, AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif, Method method, int declarationOrderInAspect, String aspectName) {
this.declaredPointcut = ajexp;
this.method = method;
this.atAspectJAdvisorFactory = af;
this.aspectInstanceFactory = aif;
this.declarationOrder = declarationOrderInAspect;
this.aspectName = aspectName;
if (aif.getAspectMetadata().isLazilyInstantiated()) {
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut =
Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif);
this.lazy = true;
}
else {
// singleton aspect.
// 实例化的Advice
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
// pointcut对象
this.pointcut = declaredPointcut;
this.lazy = false;
}
}
// 实例化Advice
private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {
return this.atAspectJAdvisorFactory.getAdvice(
this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
}
/** ReflectiveAspectJAdvisorFactory.java */
// 获取candidateAdviceMethod上的Advice对象
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut ajexp,
MetadataAwareAspectInstanceFactory aif, int declarationOrderInAspect, String aspectName) {
Class<?> candidateAspectClass = aif.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
// candidateAdviceMethod上的注解对象
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
if (aspectJAnnotation == null) {
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
// 根据Advice注解类型,实例化相应的Advice,用candidateAdviceMethod、ajexp、aif进行构造
switch (aspectJAnnotation.getAnnotationType()) {
case AtBefore: // @Before
springAdvice = new AspectJMethodBeforeAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfter: // @After
springAdvice = new AspectJAfterAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtAfterReturning: // @AfterReturning
springAdvice = new AspectJAfterReturningAdvice(candidateAdviceMethod, ajexp, aif);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing: // @AfterThrowing
springAdvice = new AspectJAfterThrowingAdvice(candidateAdviceMethod, ajexp, aif);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
case AtAround: // @Around
springAdvice = new AspectJAroundAdvice(candidateAdviceMethod, ajexp, aif);
break;
case AtPointcut: // @Pointcut
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method " + candidateAdviceMethod);
}
// 配置Advice对象
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrderInAspect);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
// 设置参数名称
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
/** ReflectiveAspectJAdvisorFactory.java */
// 获取@DeclareParents Annotation对象
private Advisor getDeclareParentsAdvisor(Field introductionField) {
DeclareParents declareParents = introductionField.getAnnotation(DeclareParents.class);
if (declareParents == null) {
// Not an introduction field
return null;
}
if (DeclareParents.class.equals(declareParents.defaultImpl())) {
// This is what comes back if it wasn't set. This seems bizarre...
// TODO this restriction possibly should be relaxed
throw new IllegalStateException("defaultImpl must be set on DeclareParents");
}
return new DeclareParentsAdvisor(
introductionField.getType(), declareParents.value(), declareParents.defaultImpl());
}
AnnotationAwareAspectJAutoProxyCreator生成代理类实例
与<aop:config>方式一样。
调用代理对象
与<aop:config>方式一样。
<aop:aspectj-autoproxy/>与<aop:config>方式本质区别是PointcutAdvisor对象实例化方式不一样:<aop:aspectj-autoproxy/>采用注解方式,而<aop:config>则采用显示的xml配置方式,集中体现在findCandidateAdvisors。