目录

配置类

AopAutoConfiguration

AspectJAutoProxyingConfiguration

ClassProxyingConfiguration

@EnableAspectJAutoProxy

AspectJAutoProxyRegistrar

AopConfigUtils

代理生成

AnnotationAwareAspectJAutoProxyCreator

Aware

BeanPostProcessor

AopInfrastructureBean

ProxyConfig

ProxyProcessorSupport

AbstractAutoProxyCreator

属性

Aware实现

BeanPostProcessor实现

InstantiationAwareBeanPostProcessor实现

SmartInstantiationAwareBeanPostProcessor实现

wrapIfNecessary

createProxy

buildAdvisors

AbstractAdvisorAutoProxyCreator

BeanFactoryAdvisorRetrievalHelper

AspectJAwareAdvisorAutoProxyCreator

extendAdvisors

AspectJProxyUtils

AnnotationAwareAspectJAutoProxyCreator

覆盖父类:findCandidateAdvisors

BeanFactoryAspectJAdvisorsBuilder

DefaultAdvisorAutoProxyCreator

InfrastructureAdvisorAutoProxyCreator


AOP是怎么生效的呢?在spring boot项目spring-boot-autoconfigure中spring.factories文件配置了自动导入:

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
... ...
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\

配置类

AopAutoConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {
}

当配置spring.aop.auto=true时(true为默认值),则导入配置。AopAutoConfiguration  内部又定义了2个配置类。

AspectJAutoProxyingConfiguration

AspectJAutoProxyingConfiguration 在定义了Advice才会导入。并且实现了2种可替换模式:JDK动态代理和cglib代理。通过spring.aop.proxy-target-class属性控制。如果没有指定,则2种模式互相配置,有接口的用动态代理,没有接口用cglib,如果指定了值,则使用指定了的方式代理对象。

 @Configuration(proxyBeanMethods = false)@ConditionalOnClass(Advice.class)static class AspectJAutoProxyingConfiguration {@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = false)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false",matchIfMissing = false)static class JdkDynamicAutoProxyConfiguration {}@Configuration(proxyBeanMethods = false)@EnableAspectJAutoProxy(proxyTargetClass = true)@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",matchIfMissing = true)static class CglibAutoProxyConfiguration {}}

ClassProxyingConfiguration

配置使用cglib动态代理的情况下,如果没有引入org.aspectj.weaver.Advice时的代理方式。

@Configuration(proxyBeanMethods = false)@ConditionalOnMissingClass("org.aspectj.weaver.Advice")@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",matchIfMissing = true)static class ClassProxyingConfiguration {ClassProxyingConfiguration(BeanFactory beanFactory) {if (beanFactory instanceof BeanDefinitionRegistry) {BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}}}

@EnableAspectJAutoProxy

导入了AspectJAutoProxyRegistrar。用于注册自动生成代理。

@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {/**是否采用cglib方式*/boolean proxyTargetClass() default false;/**是否ThreadLocal 类型。* @since 4.3.1*/boolean exposeProxy() default false;}

AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar用于注册AutoProxy。第1部分将AnnotationAwareAspectJAutoProxyCreator类型包装成BeanDefinition注册到Spring容器。第2部分将proxyTargetClass的配置设置到此BeanDefinition里。

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//1AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
//2AnnotationAttributes enableAspectJAutoProxy =AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);if (enableAspectJAutoProxy != null) {if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);}if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);}}}}

AopConfigUtils

AOP auto-proxy creator 注册处理工具类。注册了3个creator。一般BeanDefinition采用的最后一个creator:AnnotationAwareAspectJAutoProxyCreator

 private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
//使用数组,用来排序,最后一个的优先级最高。static {// Set up the escalation list...APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);}
 @Nullableprivate static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
//类型不匹配,则根据优先级确定设置哪个creator。if (!cls.getName().equals(apcDefinition.getBeanClassName())) {int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());int requiredPriority = findPriorityForClass(cls);if (currentPriority < requiredPriority) {apcDefinition.setBeanClassName(cls.getName());}}return null;}//注册beandefinition。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;}

代理生成

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator,其继承关系如下:

Aware

可以设置ClassLoader,以及BeanFactory。

public interface BeanClassLoaderAware extends Aware {void setBeanClassLoader(ClassLoader classLoader);
}public interface BeanFactoryAware extends Aware {void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}

BeanPostProcessor

public interface BeanPostProcessor {@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)            throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
//返回bean最终的类型。用于提前给出postProcessBeforeInstantiation生成的bean的类型@Nullabledefault Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {return null;}
//返回bean的可选构造函数列表。用于bean初始化的时候决定调用哪一个构造函数,如果针对某个类型的bean设置了这个回调,会采用回调设置的构造函数初始化bean@Nullabledefault Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)throws BeansException {return null;}
//用于解决循环依赖的问题default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {return bean;}}

AopInfrastructureBean

一个标记接口。

public interface AopInfrastructureBean {
}

ProxyConfig

ProxyConfig是所有产生Spring AOP代理对象的基类,它是一个数据类,主要为其AOP代理对象工厂实现类提供基本的配置属性。

public class ProxyConfig implements Serializable {private static final long serialVersionUID = -8409359707199703185L;// 如果该值为true,则proxyFactory将会使用CGLIB对目标对象进行代理,默认值为falseprivate boolean proxyTargetClass = false;// 标记是否对代理进行优化。启动优化通常意味着在代理对象被创建后,增强的修改将不会生效(即增强仅对修改之后的代理对象起作用,对修改前的修改不起作用),因此默认值为false。private boolean optimize = false;// 该属性用于空值生成的代理对象是否可以强制转型为Advised,默认值为false,表示任何生成的代理对象都可以强制转换成Advised,true是不可以,可以通过Adviced查询代理对象的一些状态
//[əʊˈpeɪk],不透明的;不传热的;迟钝的boolean opaque = false;// 标记代理对象是否应该被aop框架通过AopContext以ThreadLocal的形式暴露出去。// 当一个代理对象需要调用它自己的另外一个代理方法时,这个属性将非常有用。默认是是false,以避免不必要的拦截。
//即在方法内部互相调用时,通过((Target)AopContext.currentProxy()).innerCall(); 获取增强后当前代理对象。boolean exposeProxy = false;// 标记该配置是否需要被冻结,如果被冻结,将不可以修改增强的配置。// 如果该值为true,那么代理对象的生成的各项信息配置完成,则不容许更改,如果ProxyFactory设置完毕,该值为true,则不能对Advice进行改动,可以优化代理对象生成的性能。默认情况下该值为falseprivate boolean frozen = false;
...
}

ProxyProcessorSupport

创建代理支持类。主要功能是:检测代理类是否有用户接口(包括代理类本身),如果有则proxyTargetClass为false,否则proxyTargetClass为true。即如果有接口,则使用JDK动态代理,否则使用cglib代理。

AOP的自动代理创建器必须在所有的别的processors之后执行,以确保它可以代理到所有的小伙伴们,即使需要双重代理的那种。所以Order设置为最低优先级。

//判断是InitializingBean,DisposableBean这些配置回调接口  protected boolean isConfigurationCallbackInterface(Class<?> ifc) {return (InitializingBean.class == ifc || DisposableBean.class == ifc || Closeable.class == ifc ||AutoCloseable.class == ifc || ObjectUtils.containsElement(ifc.getInterfaces(), Aware.class));}
//内部语言接口protected boolean isInternalLanguageInterface(Class<?> ifc) {return (ifc.getName().equals("groovy.lang.GroovyObject") ||ifc.getName().endsWith(".cglib.proxy.Factory") ||ifc.getName().endsWith(".bytebuddy.MockAccess"));}
protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());boolean hasReasonableProxyInterface = false;for (Class<?> ifc : targetInterfaces) {if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&ifc.getMethods().length > 0) {hasReasonableProxyInterface = true;break;}}if (hasReasonableProxyInterface) {// Must allow for introductions; can't just set interfaces to the target's interfaces only.for (Class<?> ifc : targetInterfaces) {proxyFactory.addInterface(ifc);}}else {proxyFactory.setProxyTargetClass(true);}}

AbstractAutoProxyCreator

这个类是这个继承链中最核心的类,因为生成代理的逻辑封装在这里,它实现SmartInstantiationAwareBeanPostProcessor,在回调方法里封装了把bean对象替换为代理对象的逻辑,在getEarlyBeanReferencepostProcessBeforeInstantiationpostProcessAfterInitialization均能产生代理,postProcessBeforeInstantiation需要在配置了TargetSourceCreator之后才能生效。getEarlyBeanReference是为了解决循环依赖重写的,用来提前产生代理类,postProcessAfterInitialization在getEarlyBeanReference没有生效的情况下会被调用,这两个方法都调用了wrapIfNecessary来生成代理

属性

    /*不代理时返回对象:null*/@Nullableprotected static final Object[] DO_NOT_PROXY = null;/*没有任何增强接口对象:object*/protected static final Object[] PROXY_WITHOUT_ADDITIONAL_INTERCEPTORS = new Object[0];/** AdvisorAdapterRegistry,默认是GlobalAdvisorAdapterRegistry. */private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();/**指示代理对象是否应该冻结*/private boolean freezeProxy = false;/**拦截器名称列表. */private String[] interceptorNames = new String[0];private boolean applyCommonInterceptorsFirst = true;@Nullableprivate TargetSourceCreator[] customTargetSourceCreators;@Nullableprivate BeanFactory beanFactory;private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));private final Map<Object, Object> earlyProxyReferences = new ConcurrentHashMap<>(16);private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256);

Aware实现

BeanPostProcessor实现

初始化前不做处理,初始化后如果有必要则包装。

 public Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}@Overridepublic Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {if (bean != null) {Object cacheKey = getCacheKey(bean.getClass(), beanName);if (this.earlyProxyReferences.remove(cacheKey) != bean) {return wrapIfNecessary(bean, beanName, cacheKey);}}return bean;}

InstantiationAwareBeanPostProcessor实现

/*** 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)* AOP解析切面以及事务解析事务注解都是在这里完成的*/@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {//获取BeanClass的缓存keyObject cacheKey = getCacheKey(beanClass, beanName);if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {//advisedBeans保存了所有已经做过动态代理的Bean// 如果被解析过则直接返回if (this.advisedBeans.containsKey(cacheKey)) {return null;}// 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)// 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,// 而事务在这里是不会解析的)if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return null;}}//获取用户自定义的targetSource, 如果存在则直接在对象实例化之前进行代理创建,// 避免了目标对象不必要的实例化TargetSource targetSource = getCustomTargetSource(beanClass, beanName);//如果有自定义targetSource就要这里创建代理对象//这样做的好处是被代理的对象可以动态改变,而不是值针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象if (targetSource != null) {if (StringUtils.hasLength(beanName)) {this.targetSourcedBeans.add(beanName);}//获取Advisors, 这个是交给子类实现的Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);this.proxyTypes.put(cacheKey, proxy.getClass());//返回代理的对象return proxy;}return null;}
}
@Overridepublic boolean postProcessAfterInstantiation(Object bean, String beanName) {return true;}@Overridepublic PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {return pvs;}

SmartInstantiationAwareBeanPostProcessor实现

wrapIfNecessary

wrapIfNecessary首先会通过getAdvicesAndAdvisorsForBean得到拦截器集合,这个会交给子类实现,子类可以设计不同的策略来获取拦截器集合,如果getAdvicesAndAdvisorsForBean返回的集合不为空,就调用createProxy生成代理

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//已经有bean,直接返回。if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {return bean;}
//没有advice,直接返回bean。if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {return bean;}
//不需要处理的,直接返回。if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {this.advisedBeans.put(cacheKey, Boolean.FALSE);return bean;}// 如果有advice,则进行代理。由子类实现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;}

createProxy

使用了ProxyFactory的编程式Aop生成代理。

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,@Nullable Object[] specificInterceptors, TargetSource targetSource) {if (this.beanFactory instanceof ConfigurableListableBeanFactory) {AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);}//创建代理工厂ProxyFactory proxyFactory = new ProxyFactory();proxyFactory.copyFrom(this);//JDK还是cglib判断。if (!proxyFactory.isProxyTargetClass()) {if (shouldProxyTargetClass(beanClass, beanName)) {proxyFactory.setProxyTargetClass(true);}else {evaluateProxyInterfaces(beanClass, proxyFactory);}}//构造Advisor。Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);customizeProxyFactory(proxyFactory);proxyFactory.setFrozen(this.freezeProxy);if (advisorsPreFiltered()) {proxyFactory.setPreFiltered(true);}//返回代理对象。return proxyFactory.getProxy(getProxyClassLoader());}

buildAdvisors

此函数把拦截器包装成Advisor,是通过AdvisorAdapterRegistry类来完成。

protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {// Handle prototypes correctly...//指定拦截器name 处理成Advisor。Advisor[] commonInterceptors = resolveInterceptorNames();//所有拦截器List<Object> allInterceptors = new ArrayList<>();if (specificInterceptors != null) {//allInterceptors.addAll(Arrays.asList(specificInterceptors));if (commonInterceptors.length > 0) {if (this.applyCommonInterceptorsFirst) {allInterceptors.addAll(0, Arrays.asList(commonInterceptors));}else {allInterceptors.addAll(Arrays.asList(commonInterceptors));}}}if (logger.isTraceEnabled()) {int nrOfCommonInterceptors = commonInterceptors.length;int nrOfSpecificInterceptors = (specificInterceptors != null ? specificInterceptors.length : 0);logger.trace("Creating implicit proxy for bean '" + beanName + "' with " + nrOfCommonInterceptors +" common interceptors and " + nrOfSpecificInterceptors + " specific interceptors");}//Advisor:拦截器包装成Advisor。Advisor[] advisors = new Advisor[allInterceptors.size()];for (int i = 0; i < allInterceptors.size(); i++) {advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));}return advisors;}

AdvisorAdapterRegistry

AdvisorAdapterRegistry 实现拦截器包装成Advisor功能,以及注册AdvisorAdapter 。AdvisorAdapterRegistry通过GlobalAdvisorAdapterRegistry获取单例:DefaultAdvisorAdapterRegistry实例。

public interface AdvisorAdapterRegistry {Advisor wrap(Object advice) throws UnknownAdviceTypeException;MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;void registerAdvisorAdapter(AdvisorAdapter adapter);}
 private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();

DefaultAdvisorAdapterRegistry

DefaultAdvisorAdapterRegistry默认注册3个AdvisorAdapter。wrap方法把拦截器包装成DefaultPointcutAdvisor。DefaultPointcutAdvisor匹配任何方法。

 public DefaultAdvisorAdapterRegistry() {registerAdvisorAdapter(new MethodBeforeAdviceAdapter());registerAdvisorAdapter(new AfterReturningAdviceAdapter());registerAdvisorAdapter(new ThrowsAdviceAdapter());}

ProxyFactory

ProxyFactory是真正创建代理对象的工厂。内容太多,放后面再分析。

AbstractAdvisorAutoProxyCreator

AbstractAdivisorAutoProxyCreator主要实现了AbstractAutoProxyCreator提供的扩展点方法getAdvicesAndAdvisorsForBean,用来设置拦截器集合。通过BeanFactoryAdvisorRetrievalHelper.findAdvisorBeans()获取Advisors。

1、findCandidateAdvisors()方法先获取注册到Spring容器中的Advisor。

2、findAdvisorsThatCanApply()过滤Advisor,Advisor(切点)包含了Pointcut(切点)和Advice(增强),findAdvisorsThatCanApply方法的过滤就是利用Advisor中Pointcut匹配Class或Method来达到过滤的目的。

3、extendAdvisors()扩展Adviors,由子类实现。

 @Nullableprotected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable 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) {
//1.List<Advisor> candidateAdvisors = findCandidateAdvisors();
//2.List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
//3.extendAdvisors(eligibleAdvisors);if (!eligibleAdvisors.isEmpty()) {eligibleAdvisors = sortAdvisors(eligibleAdvisors);}return eligibleAdvisors;}
 protected List<Advisor> findCandidateAdvisors() {Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");return this.advisorRetrievalHelper.findAdvisorBeans();}

BeanFactoryAdvisorRetrievalHelper

从容器中获取Spring Advisor bean : 也就是实现了接口org.springframework.aop.Advisorbean

 public List<Advisor> findAdvisorBeans() {//获取Advisor的nameString[] advisorNames = this.cachedAdvisorBeanNames;if (advisorNames == null) {//查找Advisor.class类型的bean的name。不要在此处初始化FactoryBeans,让auto-proxy creator处理。advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);this.cachedAdvisorBeanNames = advisorNames;}if (advisorNames.length == 0) {return new ArrayList<>();}List<Advisor> advisors = new ArrayList<>();for (String name : advisorNames) {if (isEligibleBean(name)) {if (this.beanFactory.isCurrentlyInCreation(name)) {if (logger.isTraceEnabled()) {logger.trace("Skipping currently created advisor '" + name + "'");}}else {try {//获取Advisoradvisors.add(this.beanFactory.getBean(name, Advisor.class));}catch (BeanCreationException ex) {... ...}}}}return advisors;}

AspectJAwareAdvisorAutoProxyCreator

Aspectj的实现方式,也是Spring Aop中最常用的实现方式,如果用注解方式,则用其子类AnnotationAwareAspectJAutoProxyCreator

重写了父类的extendAdvisors()。作用就是在所有的advisors节点最前面插入一个Advisor(有advisors节点前提下,DefaultPointcutAdvisor),此Advisor比较特殊它的Pointcut是全类型匹配的(匹配所有Class和Method),它主要功能是在于它的Advice(增强),它的Advice实现是ExposeInvocationInterceptor类,看类的名称就知道,对外暴露的类,就是所有Advice调用链的第一环,ExposeInvocationInterceptor作用就是将调用信息存在ThreadLocal实现的上下文信息里,供调用链后续的Advice获取使用。

extendAdvisors

 @Overrideprotected void extendAdvisors(List<Advisor> candidateAdvisors) {AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);}

AspectJProxyUtils

AspectJ代理工具类。

 private static boolean isAspectJAdvice(Advisor advisor) {return (advisor instanceof InstantiationModelAwarePointcutAdvisor ||advisor.getAdvice() instanceof AbstractAspectJAdvice ||(advisor instanceof PointcutAdvisor &&((PointcutAdvisor) advisor).getPointcut() instanceof AspectJExpressionPointcut));}
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {// Don't add advisors to an empty list; may indicate that proxying is just not requiredif (!advisors.isEmpty()) {boolean foundAspectJAdvice = false;for (Advisor advisor : advisors) {// Be careful not to get the Advice without a guard, as this might eagerly// instantiate a non-singleton AspectJ aspect...if (isAspectJAdvice(advisor)) {foundAspectJAdvice = true;break;}}if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {advisors.add(0, ExposeInvocationInterceptor.ADVISOR);return true;}}return false;}
 public static final Advisor ADVISOR = new DefaultPointcutAdvisor(INSTANCE) {@Overridepublic String toString() {return ExposeInvocationInterceptor.class.getName() +".ADVISOR";}};

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator:目前最常用的AOP使用方式。spring aop 开启注解方式之后,该类会扫描所有@Aspect()注释的类,生成对应的adviosr。目前SpringBoot框架中默认支持的方式,自动配置。

通过BeanFactoryAspectJAdvisorsBuilder创建AspectJ Advisor。

覆盖父类:findCandidateAdvisors

 @Overrideprotected List<Advisor> findCandidateAdvisors() {List<Advisor> advisors = super.findCandidateAdvisors();// 利用了aspectj来解析注解了@Aspectif (this.aspectJAdvisorsBuilder != null) {advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());}return advisors;}

BeanFactoryAspectJAdvisorsBuilder

BeanFactoryAspectJAdvisorsBuilder是一个Spring AOP内部工具类,该工具类用来从bean容器,也就是BeanFactory中获取所有使用了@AspectJ注解bean,最终用于自动代理机制(auto-proxying)。

buildAspectJAdvisors() 方法将所有 @AspectJ bean advice 方法包装成Spring Advisor列表返回:
1. 从容器中找到所有@AspectJ注解的bean;
2. 将找到的每个@AspectJ bean的每个advice方法封装成一个Spring Advisor;
3. 缓存找到的Spring Advisor;
4. 将上述找到的所有Spring Advisor组织成一个列表返回

 public List<Advisor> buildAspectJAdvisors() {List<String> aspectNames = this.aspectBeanNames;if (aspectNames == null) {//线程安全处理。二次check 方法synchronized (this) {aspectNames = this.aspectBeanNames;if (aspectNames == null) {List<Advisor> advisors = new ArrayList<>();aspectNames = new ArrayList<>();// 获取所有类型为Object的bean的名称,基本上也就是说所有的bean的名称了// includeNonSingletons:true=>包含单例,非单例bean// allowEagerInit:false=>不要初始化lazy-init singletons和FactoryBean创建的beanString[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);for (String beanName : beanNames) {                 if (!isEligibleBean(beanName)) {// 本实例自己提供的筛查条件,缺省实现总是返回true,// 子类可以覆盖该方法提供自己的实现continue;}Class<?> beanType = this.beanFactory.getType(beanName);if (beanType == null) {continue;}// 检测该bean是否使用了注解@AspectJif (this.advisorFactory.isAspect(beanType)) {// 检测到了一个使用注解@AspectJ的beanaspectNames.add(beanName);AspectMetadata amd = new AspectMetadata(beanType, beanName);// 切面的属性为单例模式if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {MetadataAwareAspectInstanceFactory factory =new BeanFactoryAspectInstanceFactory(this.beanFactory,beanName);// 从@AspectJ注解的类,也就是AspectJ切面类中分析// 其advice方法,每个构造成一个Spring Advisor,// pointcut 信息 和 advice 信息已经包含在相应的Advisor// 对象中List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);// 单例模式,只需要将生成的Advisor添加到缓存if (this.beanFactory.isSingleton(beanName)) {this.advisorsCache.put(beanName, classAdvisors);}// 多实例模式,需要保存工厂类,便于下一次再次生成Advisor实例。else {this.aspectFactoryCache.put(beanName, factory);}advisors.addAll(classAdvisors);}else {// 非单例模式,每个实例处理一次。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 ArrayList<>();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;}

AspectJAdvisorFactory

为AspectJ的切面构造Advisor,也就是说处理@Aspect修饰的类。构造器默认使用的是ReflectiveAspectJAdvisorFactory

public interface AspectJAdvisorFactory {boolean isAspect(Class<?> clazz);void validate(Class<?> aspectClass) throws AopConfigException;List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory);@NullableAdvisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,int declarationOrder, String aspectName);@NullableAdvice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName);
}

DefaultAdvisorAutoProxyCreator

扩展isEligibleAdvisorBean,通过配置的prefix来过滤adivisor bean。

 @Overrideprotected boolean isEligibleAdvisorBean(String beanName) {if (!isUsePrefix()) {return true;}String prefix = getAdvisorBeanNamePrefix();return (prefix != null && beanName.startsWith(prefix));}

InfrastructureAdvisorAutoProxyCreator

扩展isEligibleAdvisorBean,这个过滤条件是,只选择框架级别(beanDefinition的role为ROLE_INFRASTRUCTURE)的Adivisor来进行对符合条件的对象进行织入,生成代理。

 @Overrideprotected boolean isEligibleAdvisorBean(String beanName) {return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);}

Spring AOP源码解析(二)—— AOP引入相关推荐

  1. Spring AOP源码解析-拦截器链的执行过程

    一.简介 在前面的两篇文章中,分别介绍了 Spring AOP 是如何为目标 bean 筛选合适的通知器,以及如何创建代理对象的过程.现在得到了 bean 的代理对象,且通知也以合适的方式插在了目标方 ...

  2. Spring AOP源码(1)—<aop:config/>AOP配置标签解析【一万字】

      基于最新Spring 5.x,对Spring AOP中的<aop:config/>标签的解析源码进行了详细分析,这是Spring AOP源码的入口!   此前我们已经详细学习了Spri ...

  3. 25-Spring源码解析之AOP(4)——创建AOP代理(1)

    Spring版本:<version>5.2.1.RELEASE</version> 文章目录 一.`Bean`的创建过程 二.创建切面类`LogAspects` 2.1 箭头( ...

  4. spring事务源码解析

    前言 在spring jdbcTemplate 事务,各种诡异,包你醍醐灌顶!最后遗留了一个问题:spring是怎么样保证事务一致性的? 当然,spring事务内容挺多的,如果都要讲的话要花很长时间, ...

  5. spring boot 源码解析23-actuate使用及EndPoint解析

    前言 spring boot 中有个很诱人的组件–actuator,可以对spring boot应用做监控,只需在pom文件中加入如下配置即可: <dependency><group ...

  6. 【深度学习模型】智云视图中文车牌识别源码解析(二)

    [深度学习模型]智云视图中文车牌识别源码解析(二) 感受 HyperLPR可以识别多种中文车牌包括白牌,新能源车牌,使馆车牌,教练车牌,武警车牌等. 代码不可谓不混乱(别忘了这是职业公司的准产品级代码 ...

  7. Spring源码深度解析(郝佳)-学习-源码解析-创建AOP静态代理实现(八)

    继上一篇博客,我们继续来分析下面示例的 Spring 静态代理源码实现. 静态 AOP使用示例 加载时织入(Load -Time WEaving,LTW) 指的是在虚拟机载入字节码时动态织入 Aspe ...

  8. Spring AOP源码解析(一)——核心概念

    目录 Pointcut ClassFilter MethodMatcher Advisor IntroductionAdvisor PointcutAdvisor AbstractPointcutAd ...

  9. Spring AOP源码解析——AOP动态代理原理和实现方式

    2019独角兽企业重金招聘Python工程师标准>>> Spring介绍 Spring(http://spring.io/)是一个轻量级的Java 开发框架,同时也是轻量级的IoC和 ...

  10. Spring AOP源码解析——专治你不会看源码的坏毛病!

    昨天有个大牛说我啰嗦,眼光比较细碎,看不到重点.太他爷爷的有道理了!要说看人品,还是女孩子强一些. 原来记得看到一个男孩子的抱怨,说怎么两人刚刚开始在一起,女孩子在心里就已经和他过完了一辈子.哥哥们, ...

最新文章

  1. 女程序员也有35岁危机焦虑吗?
  2. 强化学习ppt_机器学习原理、算法与应用配套PPT第四部分(深度学习概论、自动编码器、强化学习、聚类算法、半监督学习等)...
  3. pythonspark集群模式运行_有关python numpy pandas scipy 等 能在YARN集群上 运行PySpark
  4. 从无到有算法养成篇-线性表历练
  5. 修改win7编码为utf-8
  6. SQL 2005 新功能
  7. volley三种基本请求图片的方式与Lru的基本使用:正常的加载+含有Lru缓存的加载+Volley控件networkImageview的使用...
  8. Centos6.X安装smokeping
  9. 22.搜索大纲及重定向(Search Synonyms and Re-directs)
  10. 如何用drawInRect()显示中文?
  11. 数据结构实验题:用栈求解n皇后问题
  12. Openwrt 摄像头使用
  13. 电子设备常见的音视频接口
  14. jsdroid 教程_ps教程自学平台
  15. 再见python你好julia_再见,Python2。你好,Python3
  16. Apache 架构师的 30 条设计原则
  17. 微信html页面缓存问题,浅谈微信页面入口文件被缓存解决方案_简单_前端开发者...
  18. php数据统计模板,PHP如何使用Echarts生成数据统计报表
  19. 英菲克I9_H8_当贝纯净桌面-YYF定制-线刷固件包
  20. 招投标知识分享:影响投标报价编制的8大重要因素

热门文章

  1. android游戏开发框架libgdx的使用(二十四)—physics-body-editor配合Box2D加快开发
  2. open source的最大好处是什么?
  3. 【深入理解JVM】JVM概述
  4. 【Spring学习】Spring简介
  5. go defer性能测试
  6. Git 2.17改进了移动代码差异比较和对象搜索
  7. DNS子域授权及view(三)
  8. IOS 程序猿 UITbleView 篇
  9. 用GNS3做PIX防火墙ICMP实验
  10. VS2008 连接 SAP 4.6C RFC 经验分享(折腾了两天)