今天看啥  ›  专栏  ›  hahaeee

SpringAOP分析

hahaeee  · 掘金  ·  · 2018-03-31 15:41

SpringAOP分析

概念定义

Advice

定义: 干什么

PointCut

定义: 在哪干

Advisor

定义:组装Advice和PointCut,在哪里干什么

AOP启动过程

AopAutoConfiguration

从SpringBoot的aop自动配置开始入手

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = false)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
   public static class JdkDynamicAutoProxyConfiguration {

   }

   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = true)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
   public static class CglibAutoProxyConfiguration {

   }

}

可以是使用**@EnableAspectJAutoProxy**来开启aop自动代理

根据spring.aop.proxy-target-class属性来觉得是否使用cglib生成代理

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

  //是否使用cglib方式生成代理,默认使用jdk代理方式
   boolean proxyTargetClass() default false;

   //TODO 暂时不知道啥用
   boolean exposeProxy() default false;

}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
  	//通过参数传入BeanDefinitionRegistry对象,自行注册需要的BeanDefinition
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		//注册AutoProxyCreator到容器中
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
		//解析@EnableAspectJAutoProxy属性
		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
      	//使用cglib代理
		if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
			AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
		}
        //TODO 不知道啥用
		if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
			AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
		}
	}
}

#org.springframework.aop.config.AopConfigUtils
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
      "org.springframework.aop.config.internalAutoProxyCreator";
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
  //判断容器中是否已经注册AUTO_PROXY_CREATOR_BEAN_NAME
  if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
    //没啥用,不用看
    ...
      return null;
  }
  //容器中没有AUTO_PROXY_CREATOR_BEAN_NAME的定义,注册到容器中
  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;
}

过程总结:

  1. 注册org.springframework.aop.config.internalAutoProxyCreator到容器中

注意:org.springframework.aop.config.internalAutoProxyCreator只是BeanDefintion的名字而已,不是一个类名.其对应的真实类是org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator

来看一下AbstractAutoProxyCreator全家福

AbstractAutoProxyCreator

从全家福中我们可以看到AutoProxyCreator实现类大致分为两种:

  • 基于AOP标准概念(Advice,PointCut)
  • 基于名称匹配

从上面的全家福中可以看到以上3个都是属于第一种的,为何AopConfigUtils只提供了这3中AutoProxyCreator的注册? TODO暂时给不出解释

代理创建过程

猜测:代理对象的创建时机应该是在实例化完成之后找到匹配的切面,然后组装成一个代理对象

基于这种猜测我们在AbstractAutoProxyCreator中找到对BeanPostProcessor.postProcessAfterInitialization()的实现

AbstractAutoProxyCreator是个抽象类,并实现了几个Spring生命周期方法(模板方法模式)

#AbstractAutoProxyCreator
//对象实例化完成之后调用
@Override
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;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  //抽象,匹配切面 
  Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
  if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    //创建代理对象
    Object proxy = createProxy(
      bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
  }

  this.advisedBeans.put(cacheKey, Boolean.FALSE);
  return bean;
}

过程总结:

  1. 得到匹配的Advice

    切面匹配过程,下面会详细讲

  2. 织入Advice,生成代理

    protected Object createProxy(
    		Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
      ProxyFactory proxyFactory = new ProxyFactory();
      proxyFactory.copyFrom(this);
    
      //是否使用cglib生成代理
      if (shouldProxyTargetClass(beanClass, beanName)) {
        proxyFactory.setProxyTargetClass(true);
      }
      //添加Advisor
      Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
      for (Advisor advisor : advisors) {
        proxyFactory.addAdvisor(advisor);
      }
      //创建代理
      return proxyFactory.getProxy(getProxyClassLoader());
    }
    protected Advisor[] buildAdvisors(String beanName, Object[] specificInterceptors) {
      //公共Interceptor
      Advisor[] commonInterceptors = resolveInterceptorNames();
      //commonInterceptors+specificInterceptors
      List<Object> allInterceptors = new ArrayList<Object>();
      ...
        Advisor[] advisors = new Advisor[allInterceptors.size()];
      ...
        return advisors;
    }
    
    #org.springframework.aop.framework.ProxyFactory
    public Object getProxy(ClassLoader classLoader) {
       return createAopProxy().getProxy(classLoader);
    }
    
    #org.springframework.aop.framework.ProxyCreatorSupport
    protected final synchronized AopProxy createAopProxy() {
    	...
      return getAopProxyFactory().createAopProxy(this);
    }
    
    #org.springframework.aop.framework.DefaultAopProxyFactory
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    	//是否使用cglib进行代理
    	if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    	    Class<?> targetClass = config.getTargetClass();
       		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
       		return new JdkDynamicAopProxy(config);
        	}
             //cglib代理
    		return new ObjenesisCglibAopProxy(config);
    	}
        else {
    	    return new JdkDynamicAopProxy(config);
        }
    }
    
    

具体的Proxy对象生成过程我们暂且不看

以上则是AbstractAutoProxyCreator创建代理的过程

下面我们分别来看基于AOP标准和基于名称匹配的两大阵营是如何获取切面的

切面匹配过程

基于AOP标准

#org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}
	
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  //抽象,获取可能匹配的Advice
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  //抽象,获取合格的Advice
  List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    //对Advice进行排序
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}

基于Advisor接口

#org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
protected List<Advisor> findCandidateAdvisors() {
	return this.advisorRetrievalHelper.findAdvisorBeans();
}
#org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper
public List<Advisor> findAdvisorBeans() {
		//返回所有Advisor接口的实现类
		String[] advisorNames = null;
		...
		advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Advisor.class, true, false);
		...
		List<Advisor> advisors = new LinkedList<Advisor>();
		for (String name : advisorNames) {
			...
			advisors.add(this.beanFactory.getBean(name, Advisor.class));
			...
		}
		return advisors;
	}

基于AspectJ注解

#org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
@Override
protected List<Advisor> findCandidateAdvisors() {
   //获取基于Advisor接口的实现类
   List<Advisor> advisors = super.findCandidateAdvisors();
   //另加入基于AspectJ注解的Advisor(通过适配器模式包装成一个Advisor)
   advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   return advisors;
}

#org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder
public List<Advisor> buildAspectJAdvisors() {
	//1.从工厂中获取所有带有@Aspect注解的实现类
    //2.解析其中所有方法上的注解
    //3.通过适配器模式包装成Advisor返回
    
    //过程不过多分析
    ....
     return advisors;
}

基于名称匹配

#org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
   if (this.beanNames != null) {
      for (String mappedName : this.beanNames) {
         //如果匹配则返回
        if(){
          return PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS;
        }
      }
   }
  //名称不匹配则返回DO_NOT_PROXY标志位 ,不进行代理
   return DO_NOT_PROXY;
}

BeanNameAutoProxyCreator只能对所有注册的BeanName适用相同的Interceptor




原文地址:访问原文地址
快照地址: 访问文章快照