之前看了王福强老师的《Spring揭秘》一书,对Spring AOP有了一个概念,但是毕竟版本比较老,无法与现在的框架使用相结合,然后又看了尚硅谷雷神的Spring注解开发的视频,跟着和源码走了一遍,突然觉得和王福强老师的《Spring 揭秘》就结合起来了,一种豁然开朗的感觉,因此写了这样一篇博客,写的不好的地方请见谅
Spring AOP 知识点总结
AOP 中的概念
AOP,面向切面编程,其中有以下的概念:
JoinPoint
:切入点,即在什么时间点织入其他的逻辑,虽然有很多类型的织入,如方法执行,方法调用,字段设置等,理论上系统的每个点都可以作为切入点,但是Spring AOP
仅仅支持方法执行的织入,这已经能满足80%的需要了Pointcut
:用来描述JoinPoint
的,比如说AspectJ
的expression
表达式Advise
:通知,即织入JoinPoint
的横切逻辑,我的理解是这个东西就是在系统运行到JoinPoint
的时候执行的一段代码Aspect
:切面,就好像面向对象的类,其中包含了Pointcut
和Advise
Java如何实现AOP
Java是通过代理模式来实现AOP的,代理模式其中有静态代理和动态代理,主要使用的是动态代理。动态代理又分为两种,JDK
自带的基于接口的动态代理和CGLIB
的基于子类的动态代理
JDK提供的动态代理主要有一个类和一个接口组成,即java.lang.reflect.Proxy
类和java.lang.reflect.InvocationHandler
接口,Proxy
类用来生成动态代理实例,而InvocationHandler
用于实现调用逻辑。由于这种方式是基于接口的,因此,如果一个类没有实现任何接口,就无法使用这种方式了
CGLIB是通过动态字节码生成技术,为需要代理的目标对象动态生成一个子类来进行扩展。这种方式主要使用的是net.sf.cglib.proxy.MethodInterceptor
接口。由于这种方式是基于子类的,因此,如果代理的方法是是子类无法重写的,如private\final
等,则无法完成代理
Spring AOP中关于AOP各个概念的实现
Pointcut
Spring AOP 定义了org.springframework.aop.Pointcut
接口作为所有的Pointcut的顶层抽象
public interface Pointcut {
ClassFilter getClassFilter();
MethodMathcher getMethodMatcher();
Point True = TruePointcut.INSTANCE;
}
ClassFilter
和 MethodMatcher
分别匹配织入操作的对象和方法,前面提过,Spring AOP
仅支持方法执行的织入,因此需要定位一个方法,就需要从类,方法签名
两个方面来进行匹配
ClassFilter
ClassFilter
接口的作用就是对JoinPoint
进行类级别的匹配,以下是ClassFilter
接口的定义
public interface ClassFilter {
boolean matches(Class clazz);
ClassFilter true = TrueClassFilter.INSTANCE;
}
可以看到,ClassFilter
接口中只有一个matches
方法,传入参数是一个Class
对象,返回值为布尔类型,如果类中的方法需要进行织入逻辑的时候,那么往matches
方法传入该类的Class对象就会返回true
MethodMatcher
MethodMatcher
接口顾名思义,就是只有匹配的方法才会进行AOP织入的逻辑,下面是MethodMatcher
接口的定义
public interface MethodMatcher {
boolean matches(Method method, Class targetClass);
boolean isRuntime();
boolean matches(Method method, Class targetClass, Object[] args);
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
可以看到,该接口有三个方法,其中还有两个同名的matches
方法进行重载,它俩的区别就在于是否需要对织入的方法进行更精细的控制。这两个matches方法
的分界线就在于isRuntime
方法,如果isRuntime
方法返回true
,那么有三个参数的matches
方法就会被调用,三个参数的matches
方法多出来的参数就是方法调用时传入的参数
执行逻辑如下描述:
- 首先执行两个参数的
matches
方法,如果该方法返回false
,说明不需要织入,直接结束判断;如果该方法返回true
,再调用isRuntime
方法 - 如果
isRuntime
方法返回false
,说明该方法需要切入,结束判断;如果isRuntime
方法返回true
,说明还需要进行参数的检查,接着调用三参数的matches
方法 - 如果三参数的
matches
方法返回true
,需要切入,反之则不需要
按照isRuntime
方法的返回值,MethodMatcher
也分为了两种类型,isRuntime
返回false
的MethodMatcher
称为StaticMethodMatcher
,相对的其它MethodMatcher
称为DynamicMethodMatcher
。StaticMethodMatcher
的性能会比较高,因为可以把结果缓存起来,而DynamicMethodMatcher
因为每次都要根据方法调用传入的参数进行判断,所以无法缓存,性能比较差
Pointcut实现类
基于上述的MethodMatcher
类型,Pointcut
也分为了两类,即StaticMethodMatcherPointcut
和DynamicMethodMatcherPointcut
,以下是其中的一些实现类列举,具体实现可以查看源码
NameMatchMethodPointcut
JdkRegexpMethodPointcut
AnnotationMatchingPointcut
ComposablePointcut
ControlFlowPointcut
如果Spring AOP
提供的Pointcut
实现类无法满足需要,可以自定义Pointcut
Advice
Spring AOP
中的Advice
顶级接口定义是org.aopalliance.aop.Adivce
接口,该接口是一个空接口,其子接口有org.springframework.aop.AfterAdvice
,org.springframework.aop.BeforeAdivce
,org.aopalliance.intercept.Interceptor
public interface Advice {
}
per-class类型的Advice
上图中的Advice
类型都是per-class
类型的,per-class
类型的Advice
的实例可以在目标对象类的所有实例之间共享。接下来介绍这些per-class
类型Advice
的定义
org.springframework.aop.MethodBeforeAdvice
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable;
}
org.springframework.aop.ThrowsAdvice
public interface ThrowsAdvice extends AfterAdvice {
}
/*
虽然该接口没有定义任何接口,但是实现该接口时候,方法定义需要遵循下面的模板。其中[]中的三个参数可以省略,这样可以根据将要拦截的Throwable的不同类型,在同一个ThrowsAdvice中实现多个afterThrowing方法
**/
void afterThrowing([Method, args, target], ThrowableSubclass);
org.springframework.aop.AfterReturningAdvice
public interface AfterReturningAdvice extends AfterAdvice {
void afterReturning(Object returnValue, Method method, Object[] args, Object target);
}
org.aopaliance.intercept.MethodInterceptor
public interface MethodInterceptor extends Interceptor {
Object invoke(MethodInvocation invocation) throws Throwable;
}
per-instance类型的Advice
没怎么见过这种类型的使用,就暂时略过了,很少见
Advisor
Spring
中的Advisor
通常只持有一个Pointcut
和一个Advice
,可以认为是一种特殊的Aspect
,其中的定义为
org.springframework.aop.Advisor
public interface Advisor {
Advice EMPTY_ADVICE = new Advice() {};
Advice getAdvice();
boolean isPerInstance();
}
Advisor中定义了两个方法,其中getAdvice用来获取Advice;而isPerInstance标识此Advice是与特定实例相关联的,但是这个方法在当前的框架中并没用使用,它总是返回true
其中Advisor
有两个分支,PointcutAdvisor
和IntroductionAdvisor
,前者为per-class
类型的Advice
的Advisor
,后者是per-instance
类型的Advice
的Advisor
,重点看一下PointcutAdvisor的定义
org.springframework.aop.PointcutAdvisor
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
很明显其中只定义了一个方法,用来获取Pointcut
在注解开发Spring AOP中,主要的实现类就是InstantiationModelAwarePointcutAdvisorImpl,详细参考源码
当某个织入点有多个横切逻辑时,注意这些逻辑的执行顺序,可能会影响系统
Spring AOP的织入
织入就是将横切逻辑集成到系统中,完成织入操作的就是织入器,Spring AOP
中的织入器就是org.springframework.aop.framework.ProxyFactory
,以下时该类的定义
org.springframework.aop.framework.ProxyFactory
public class ProxyFactory extends ProxyCreatorSupport {
public ProxyFactory() {
}
public ProxyFactory(Object target) {
setTarget(target);
setInterfaces(ClassUtils.getAllInterfaces(target));
}
public ProxyFactory(Class<?>... proxyInterfaces) {
setInterfaces(proxyInterfaces);
}
public ProxyFactory(Class<?> proxyInterface, Interceptor interceptor) {
addInterface(proxyInterface);
addAdvice(interceptor);
}
public ProxyFactory(Class<?> proxyInterface, TargetSource targetSource) {
addInterface(proxyInterface);
setTargetSource(targetSource);
}
public Object getProxy() {
return createAopProxy().getProxy();
}
@SuppressWarnings("unchecked")
public static <T> T getProxy(Class<T> proxyInterface, Interceptor interceptor) {
return (T) new ProxyFactory(proxyInterface, interceptor).getProxy();
}
@SuppressWarnings("unchecked")
public static <T> T getProxy(Class<T> proxyInterface, TargetSource targetSource) {
return (T) new ProxyFactory(proxyInterface, targetSource).getProxy();
}
public static Object getProxy(TargetSource targetSource) {
if (targetSource.getTargetClass() == null) {
throw new IllegalArgumentException("Cannot create class proxy for TargetSource with null target class");
}
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.setTargetSource(targetSource);
proxyFactory.setProxyTargetClass(true);
return proxyFactory.getProxy();
}
}
AopProxy
要了解ProxyFactory
,需要先从org.springframework.aop.framework.AopProxy
说起,该接口的定义如下
public interface AopProxy {
Object getProxy();
Object getProxy(ClassLoader classLoader);
}
可以看到AopProxy
定义了获取代理的方法。对于不同的代理实现机制,Spring AOP
提供了不同的AopProxy
子类实现,目前Spring AOP
主要提供了JDK
动态代理和CGLIB
两种机制的AopProxy
的实现,具体的实现参考源码
上图列出了SpringAOP
中的一些关键类
AopProxyFactory
各种AopProxy
实例化的实现是采用了工厂模式,通过org.springframework.aop.framework.AopProxyFactory
来进行,其中AopProxyFactory
的接口定义如下,它只有一个实现类,即org.springframework.aop.framework.DefaultAopProxyFactory
org.springframework.aop.framework.AopProxyFactory
public interface AopProxyFactory {
AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException;
}
可以看到AopProxyFactory
通过AdvisedSupport
来创建一个AopProxy
其中DefaultAopProxyFactory
的实现逻辑也很简单
if (!NativeDetector.isNativeImage() && (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
// 创建CglibAopProxy实例返回
} else {
// 创建JdkDynamicAopProxy实例返回
}
以上逻辑可以看到,如果当前JVM运行环境不是GraalVM
并且满足以下条件之一就使用CGLIB
:
- AOP配置中
optimize
参数为true
- AOP配置中
proxyTargetClass
参数为true
- 用户没有提供代理接口
AdvisedSupport
上图展示了AdvisedSupport
继承了ProxyConfig
类,实现了Advised
接口
AdvisedSupport
其实就是一个生成代理对象所需要的信息的载体,其中的信息可以分为两类,一类是以org.springframework.aop.framework.ProxyConfig
,它记载了生成代理对象的控制信息;一类是以org.springframework.aop.framework.Advised
,它承载了生菜代理对象所需要的必要信息,如目标类、Advice、Advisor
以下是ProxyConfig
的定义信息,其中定义了5个boolean
类型的变量
org.springframework.aop.framework.ProxyConfig
private boolean proxyTargetClass = false;
private boolean optimize = false;
boolean opaque = false;
boolean exposeProxy = false;
private boolean frozen = false;
proxyTargetClass
:如果该属性为true
,那么ProxyFactory
将会使用CGLIB
对目标对象进行代理optimize
:如果该属性为true
,则表示代理对象需要采取进一步的优化措施,如代理对象生成后,代理信息发生了改变,代理对象是否可以忽略这些变动。相应的,如果该属性为true
,ProxyFactory
也会使用CGLIB
代理opaque
:控制生成的代理对象是否可以强制转化成Advised
,默认是false
,即可以强制转化。通过强制转化成Advised
,可以查询到代理对象的一些状态exposeProxy
:该属性控制SpringAOP
在生成代理对象时,是否将代理对象绑定到ThreadLocal
上。如果目标对象需要访问当前代理对象,可以通过AopContext.currentProxy()
取得,常用于事务frozen
:如果frozen
为true
,说明一旦为代理对象生成的各项信息配置完成,则不允许修改
除了ProxyConfig
提供的控制信息以外,还需要生成代理对象的一些具体信息,其中包括需要代理的目标类,横切逻辑等,这些信息就包含在Advised
中
上图中ProxyCreatorSupport
类,抽取了一些公用的逻辑,子类可以根据需要重写方法。ProxyCreatorSupport
持有了一个DefaultAopProxyFactory
对象,用它来生成各种AopProxy
public class ProxyCreatorSupport extends AdvisedSupport {
private AopProxyFactory aopProxyFactory;
protected final synchronized AopProxy createAopProxy() {
if (!this.activate) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
}
除了ProxyFactory以外,ProxyCreatorSupport还有其他的子类
ProxyFactoryBean
ProxyFactoryBean
是SpringAOP
与Spring
容器的一个桥梁,它专门用来生产Proxy
,需要注意的是,ProxyFactoryBean
正确的断句应该是Proxy+FactoryBean
,即它产生的对象是Proxy
,而不是ProxyFactory
。
ProxyFactoryBean
的实现并不复杂,直接从父类的createAopProxy
方法创建代理对象返回即可。既然是一个FactoryBean
,那么就需要关注它的getObject()
方法了
public Object getObject() throws BeansException {
initializeAdvisorChain();
if (isSingleton()) {
return getSingletonInstance();
}
else {
if (this.targetName == null) {
logger.info("Using non-singleton proxies with singleton targets is often undesirable. " +
"Enable prototype proxies by setting the 'targetName' property.");
}
return newPrototypeInstance();
}
}
FactoryBean
定义中要求标明返回的对象是singleton
还是prototype
,针对这两种情况会返回不同的代理对象。如果isSingleton
方法返回true
,则会通过singleInstance
(Object类型)缓存生成的代理对象
ProxyFactoryBean
在继承父类ProxyCreatorSupport
的所有配置属性外,还有几个额外的属性
-
proxyInterfaces
:配置需要代理哪些接口。即使不指定,ProxyFactoryBean
也可以自动检测目标对象所实现的接口来进行代理,这个功能由autodetectInterfaces
属性来控制 -
interceptorNames
:这个属性用来指定多个将要织入目标对象的Advice,拦截器以及Advisor
。这样就不需要像ProxyFactory
那样通过addAdvice
或addAdvisor
方法一个一个的添加了。- 如果没有为
ProxyFactoryBean
显式的指定目标对象,则可以在interceptorNames
的最后一个位置放目标对象的bean
定义名称。最好别用 -
interceptorNames
支持采用*
通配符的方式来设置Advisors
- 如果没有为
-
singleton
:控制是否以单例的模式返回代理对象
自动代理机制
虽然可以使用ProxyFactory
或者ProxyFactoryBean
来创建AOP
代理,但是每一个目标对象都需要一个ProxyFactory
或者ProxyFactoryBean
,在目标对象很多的情况下,工作量是难以想象的。因此Spring AOP
给出了自动代理的机制
原理
自动代理的实现原理是基于BeanPostProcessor
概念之上的,只要提供一个BeanPostProcessor
,在其中实现一个逻辑,当对象实例化的时候,为其生成代理对象并返回,而不是实例化后的目标对象本身,即可完成自动代理
伪代码示例如下:
for (bean in SpringContainer) {
if (符合拦截条件) {
return createProxyFor(bean);
} else {
return createInstance(bean);
}
}
因此现在的重点就在于如何定义拦截条件以及如何将拦截条件告知给自动代理的实现类
- 可以通过外部配置文件传入这些拦截信息
- 可以通过注解在代码中标注Pointcut拦截信息
可用的AutoProxyCreator
可以看到,AutoProxyCreator
都是ProxyConfig
的子类,因为ProxyConfig
中定义了生成代理对象的控制信息
TargetSource
TargetSource
就是一个目标类的包装,在创建AOP代理时,除了可以直接指定目标类的class对象,指定目标类的beanName外,还可以传入一个TargetSource
。最常用的TargetSource
就是SingletonTargetSource
分析AOP代理的创建过程
我们使用AOP的时候,往往就是通过在配置类中加上@EnableAspetJAutoProxy
注解,之后只需要用@Aspect
放在自己的切面类上,再在切面类中定义横切逻辑的方法,使用诸如@Pointcut、@Before、@AfterReturning
等等注解定义Pointcut
和Advised
即可完成AOP的编程,下面就来分析这些是如何完成的
@EnableAspectJAutoProxy
首先看一下@EnableAspectJAutoProxy
的源码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;
boolean exposeProxy() default false;
}
可以看到其中有两个属性proxyTargetClass
和exposeProxy
,这就是前面提到的ProxyConfig
中定义的属性。此外,还通过@Import注解导入了AspectJAutoProxyRegistrar
类,这个类的作用就是往容器中注入前面提到的AutoProxyCreator
来帮我们进行自动代理,我们来看看AspectJAutoProxyRegistrar
类的源码
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 往容器中注册自动代理类,AutoProxyCreator
// 往下追溯,其实就是注入了一个AnnotationAwareAspectJAutoProxyCreator
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
// 这里是获取配置类中的EnableAspectJAutoProxy注解的信息
// 也就是上面看到的proxyTargetClass和exposeProxy
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
// 这里是根据EnableAspectJAutoProxy注解中的信息设置AutoProxyCreator的值
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
接下来重点关注一下AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry)
方法
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
// 可以看到这里就是往容器中注入了AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
/*
判断registry中是否已经有一个AUTO_PROXY_CREATOR_BEAN_NAME的beanDefinition
没有——>在后面会放一个AnnotationAwareAspectJAutoProxyCreator的定义信息
有
判断是否是AnnotationAwareAspectJAutoProxyCreator的Bean定义
不是
判断二者之间优先级,注入优先级高的那个
源代码中AnnotationAwareAspectJAutoProxyCreator的优先级是最高的,因此,最后都会注入这个Bean
**/
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;
}
// 这里是如果registry中没有定义名为AUTO_PROXY_CREATOR_BEAN_NAME的bean,则注入
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;
}
至此,可以看到,@EnableAspectJAutoProxy
的作用就是往容器中注入了一个AnnotationAwareAspectJAutoProxyCreator
AnnotationAwareAspectJAutoProxyCreator
首先需要注意的是AnnotationAwareAspectJAutoProxyCreator
实现了Ordered、BeanFactoryAware、SmartInstantiationAwareBeanPostProcessor
接口,注意不是直接实现的,父类实现了这些接口,这些接口在后面会用到
实现的接口方法
setBeanFactory()方法流程
先来分析AnnotationAwareAspectJAutoProxyCreator
的创建流程,因为AnnotationAwareAspectJAutoProxyCreator
是一个BeanPostProcessor
(SmartInstantiationAwareBeanPostProcessor
是BeanPostProcessor
的子接口),所以它的实例化是在AbstractApplicationContext
中的registerBeanPostProcessors
方法中完成的,它的实例化就是正常的Bean的流程
因为AnnotationAwareAspectJAutoProxyCreator
实现了BeanFactoryAware
接口,所以先看看它的setBeanFactory
方法
//==========AbstractAutoProxyCreator==========
public void setBeanFactory(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
//==========AbstractAdvisorAutoProxyCreator=====
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
}
initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}
//==========AnnotationAwareAspectJAutoProxyCreator=====
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
this.aspectJAdvisorsBuilder =
new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
AnnotationAwareAspectJAutoProxyCreator
并没有直接实现setBeanFactory
方法,而是继承了父类的实现,其中在父类实现的setBeanFactory
方法中又调用了initBeanFactory
方法,而AnnotationAwareAspectJAutoProxyCreator
则重写了这个方法
可以看到,在回调BeanFactoryAware
接口的方法过程中,AnnotationAwareAspectJAutoProxyCreator
主要的工作就是初始化了三个类,分别是BeanFactoryAdvisorRetrievalHelperAdapter
、ReflectiveAspectJAdvisorFactory
、BeanFactoryAspectJAdvisorsBuilderAdapter
,它们的作用如下
-
BeanFactoryAdvisorRetrievalHelperAdapter
:BeanFactoryAdvisorRetrievalHelper
的子类,用于从BeanFactory
检索标准的Spring Advisor
,用于自动代理 -
ReflectiveAspectJAdvisorFactory
:AspectJAdvisorFactory
接口的实现类,它可以从BeanFactory
检索遵循AspectJ
注解语法的类中,来创建Spring AOP
代理,使用反射来调用相应的Advise
-
BeanFactoryAspectJAdvisorsBuilderAdapter
:BeanFactoryAspectJAdvisorsBuilder
的子类,用于从BeanFactory
检索@Aspect
标注的类,并基于它们构建Spring Advisors
,用于自动代理
postProcessBeforeInstantiation方法
SmartInstantiationAwareBeanPostProcessor
是InstantiationAwareBeanPostProcessor
的子接口,而InstantiationAwareBeanPostProcessor
中定义了在Bean
实例化前后的回调,注意和BeanPostProcessor
的区别,BeanPostProcessor
定义的是Bean
初始化前后的回调,在调用BeanPostProcessor
之前,Bean已经完成了初始化,并且已经完成了属性赋值,接下来就是调用init
方法,而BeanPostProcessor
的回调就发生在init
方法的前后
所以我们主要看其中的回调方法,首先看postProcessBeforeInstantiation
方法
// 请注意,AnnotationAwareAspectJAutoProxyCreator并没有重写这个方法,该方法是在AbstractAutoProxyCreator中
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
/* 这里根据beanClass和beanName创建一个缓存的key值,这在之后做缓存时需要用到
其实就是要么返回beanName,要么返回beanClass
**/
Object cacheKey = getCacheKey(beanClass, beanName);
/*
adviseBeans中保存了对象是否需要被代理的信息,它是Map<Object, Boolean>类型的
如果该对象被代理了,则其对应的布尔值为true,反之为false
如果该对象已经在adviseBeans中了,说明之前已经走过了流程,所以不需要再继续,直接返回
如果对象是AOP相关的基础类,如Advisor,Advise,Pointcut,则说明不需要代理,直接掠过
如果对象是@Aspect注解的类,也是直接略过的
关于isInfrastructureClass和shouldSkip方法的逻辑,之后详述
**/
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}
/*
如果我们定义了TargetSourceCreator,将会在此处创建代理
防止目标bean的不必要的默认实例化,TargetSource将以自定义方式处理目标实例
如果没有,那么在前置处理的流程中不会创建代理,直接返回null
当然,按照惯用的使用注解开发AOP的流程,这一步一般是走不到的,即不会在前置处理中创建代理
**/
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
return null;
}
postProcessAfterInitialization方法
接下来看看实例化后的处理逻辑,postProcessAfterInitialization
方法
// 该方法同样是在AbstractAutoProxyCreator中
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 关键的方法在这里wrapIfNecessary方法
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
//==========AbstractAutoProxyCreator==========
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 这里如果targetSourcedBeans中包含了beanName,说明已经在前置处理中进行了代理
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
// 这里说明它不需要代理
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
// 这里和before中的处理一致
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
/*
这里通过getAdvicesAndAdvisorsForBean方法查询到bean的所有的Advisor和Advice
如果没有查询到,那说明不需要代理,在缓存中记录一下,将bean原样返回即可
如果查询到Advices和Advisors,则创建代理,记录缓存,返回代理对象
**/
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;
}
判断一个bean是否应该直接跳过的方法
isInfrastructureClass方法
isInfrastructureClass
方法是判断一个类是否是AOP的基础类的方法,以下是其方法定义
// ==========AbstractAutoProxyCreator==========
protected boolean isInfrastructureClass(Class<?> beanClass) {
boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass);
if (retVal && logger.isTraceEnabled()) {
logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
}
return retVal;
}
// AnnotationAwareAspectJAutoProxyCreator重写了isInfrastructureClass方法
/*
可以看到该方法就是在父类判断的基础上增加了对注解@Aspect的判断
如果一个类之上加上了@Aspect,也属于AOP的基础类
*/
protected boolean isInfrastructureClass(Class<?> beanClass) {
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
shouldSkip方法
这个类用来判断是否应该跳过该bean,不对此Bean做代理,该方法其实就是跳过那些加了Aspect注解的Bean
在shouldSkip
方法中调用了findCandidateAdvisors
方法获取了容器中所有的Advisor
,然后看这些Advisor的对应的beanName是否和此次需要判断的名字相同,如果相同就跳过
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
/*
可以看到,这里其实是先找到系统中所有的Advisor
然后依次判断bean是否就是这些Advisor,如果是,则可以略过,否则调用父类的shouldSkip
**/
// TODO: Consider optimization by caching the list of the aspect names
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;
}
}
return super.shouldSkip(beanClass, beanName);
}
// ==========AbstractAutoProxyCreator==========
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 该方法其实就是判断beanName是否是以beanClass的全限定名开始,以“.ORIGINAL”结尾
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
找到并构建Advisor的方法
findCandidateAdvisors
// ==========AbstractAutoProxyCreator==========
protected List<Advisor> findCandidateAdvisors() {
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();
}
// AnnotationAwareAspectJAutoProxyCreator重写了这个findCandidateAdvisors方法
// ==========AnnotationAwareAspectJAutoProxyCreator==========
protected List<Advisor> findCandidateAdvisors() {
// 调用父类的findCandidateAdvisors方法,获取Spring的标准Advisor
List<Advisor> advisors = super.findCandidateAdvisors();
// 从BeanFactory中构建所有的AspectJ的切面,添加到advisors中
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
这个方法的逻辑很简单,先从调用父类的同名方法,获取到Spring
的标准Advisor
,再调用自己的方法,构建所有的以@Aspect
标注的切面类,接下来就看看这两个方法是怎么找到所有的Advisor
的
advisorRetrievalHelper.findAdvisorBeans
先来看看父类是怎么做的,这个advisorRetrievalHelper
是保存在AbstractAdvisorAutoProxyCreator
中的,是BeanFactoryAdvisorRetrievalHelperAdapter
类型的,它的初始化是在setBeanFactory
中的,忘记的话可以看前面关于BeanFactoryAware
接口的流程,这个方法是去找到容器中用标准的方式(接口实现)实现的所有Advisor
AbstractAdvisorAutoProxyCreator
中定义了BeanFactoryAdvisorRetrievalHelperAdapter
类继承了BeanFactoryAdvisorRetrievalHelper
,并重写了其isEligibleBean
方法,该方法的作用就是判断给定的bean名称的切面类是否有资格作为一个切面类来使用,如果没有资格,则不会将其当作Aspect对待
private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {
public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
super(beanFactory);
}
@Override
protected boolean isEligibleBean(String beanName) {
return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
}
}
可以看到isEligibleBean
中又调用了AbstractAdvisorAutoProxyCreator
的isEligibleAdvisorBean
方法,以下是该方法的源码,这个方法永远返回true,子类可以根据需要重写这个方法
// ==========AbstractAdvisorAutoProxyCreator==========
protected boolean isEligibleAdvisorBean(String beanName) {
return true;
}
接下来就可以分析findAdvisorBeans
方法了,以下是findAdvisorBeans
的源码
public List<Advisor> findAdvisorBeans() {
/*
这里存储了所有的advisor类型的bean的名称
如果advisorNames为空,说明还没有进行从beanFactory中找advisor的流程
**/
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
/*
从BeanFactory中找到所有Advisor及其子类的beanName,将其赋值给advisorNames
不要在这里初始化FactoryBean,我们需要让auto-proxy应用在所有的常规bean
**/
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
// 这里根据上面找到的beanName,创建对应的Advisor
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
// 先判断这个beanName是否有资格作为切面类使用
if (isEligibleBean(name)) {
// 如果这个bean还在创建中,先跳过
if (this.beanFactory.isCurrentlyInCreation(name)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {
try {
// 从beanFactory中获取这个Bean,放到advisors中
advisors.add(this.beanFactory.getBean(name, Advisor.class));
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
/*
如果抛出的异常时BeanCurrentlyInCreationException,则先跳过,说明这个对象的依赖还没到位
如果是其他异常,抛出该异常
**/
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
aspectJAdvisorsBuilder.buildAspectJAdvisors
这个aspectJAdvisorBuilder
对象是保存在AnnotationAwareAspectJAutoProxyCreator
中的,它的类型是BeanFactoryAspectJAdvisorsBuilderAdapter
,它是BeanFactoryAspectJAdvisorsBuilder
的子类,以下是它的源码,可以看到它重写了父类的isEligibleBean
方法,调用了AnnotationAwareAspectJAutoProxyCreator
的isEligibleAspectBean
方法
这个方法的主要作用是找到容器中以@Aspect
注解实现的切面类,构造对应的Advisor
private class BeanFactoryAspectJAdvisorsBuilderAdapter extends BeanFactoryAspectJAdvisorsBuilder {
public BeanFactoryAspectJAdvisorsBuilderAdapter(
ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
@Override
protected boolean isEligibleBean(String beanName) {
return AnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
}
}
以下是AnnotationAwareAspectJAutoProxyCreator
的isEligibleAspectBean
方法。该方法的判断方式就是根据includePatterns
来匹配BeanName
// ==========AnnotationAwareAspectJAutoProxyCreator==========
protected boolean isEligibleAspectBean(String beanName) {
if (this.includePatterns == null) {
return true;
}
else {
for (Pattern pattern : this.includePatterns) {
if (pattern.matcher(beanName).matches()) {
return true;
}
}
return false;
}
}
接下来就看看buildAspectjAdvisors
方法的源码
public List<Advisor> buildAspectJAdvisors() {
// 先从aspectBeanNames找到缓存的切面类的名称
List<String> aspectNames = this.aspectBeanNames;
// 单例模式中的双重检查
if (aspectNames == null) {
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
// 从beanFactory中获取所有的beanName,遍历
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
// 判断是否有资格成为一个切面类
if (!isEligibleBean(beanName)) {
continue;
}
// 获取beanName的类型
// 我们必须要小心,不要实例化了bean,此时它们还不会被代理
// 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, false);
if (beanType == null) {
continue;
}
/*
判断它的上面是否加了Aspect注解,如果加了该注解,先将其beanName放到aspectNames中
然后遍历其beanName上的所有方法,对于加了@Before等的方法,创建一个对应的Advisor
如果创建的Advisor是单例模式的,则将其存放到advisorsCache中
否则将其对应的工厂对象放到aspectFactoryCache中,之后会从中取出来创建Advisor
将创建的Advisor放到advisors中,返回
**/
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);
AspectMetadata amd = new AspectMetadata(beanType, beanName);
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
/**
MetadataAwareAspectInstanceFactory的作用就是创建指定beanName的Advisor
**/
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();
}
/**
如果aspectNames不为空,则遍历所有的aspectName,尝试从advisorsCache中获取其对应的Advisor
如果没有获取到Advisor,则尝试创建
**/
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;
}
advisorFactory.getAdvisors
这个方法的作用是从@Aspect
标注的类中,为每个使用@Before
、@AfterThrowing
等等注解标注的方法创建一个对应的Advisor
,然后会返回这样一个Advisor
的集合,现在来分析一下这个方法的流程
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
/**
这里先取出切面类和它的beanName,然后进行校验
校验主要校验两个方面:
第一是切面类的父类不能也被@Aspect标注,且其不是抽象类
第二是这个切面类的类型是否被SpringAOP支持
**/
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
validate(aspectClass);
// 这里是包装一下MetadataAwareAspectInstanceFactory,让它只实例化一次
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
/**
这里的getAdvisorMethod的逻辑就是遍历切面类的所有方法,找出所有的没有被@Pointcut标注的方法
此外如果切面类还有父类,接口,同样会遍历找到父类和接口中的方法
**/
List<Advisor> advisors = new ArrayList<>();
for (Method method : getAdvisorMethods(aspectClass)) {
/**
这里就是遍历得到的方法,然后创建Advisor,添加到advisors
这个方法源码上加了一段注释,在Springframework5.2.7之前,会使用advisors.size()替换
下面这个硬编码的0,详细看源码注释
**/
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, 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;
}
advisorFactory.getAdvisor
现在再来看看Advisor
是怎么创建的,它的源码如下
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrderInAspect, String aspectName) {
// 这里和上面的一样,检验一下切面类
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
// 这里就是取出注解信息中的Pointcut值,如果为空,就直接返回一个null,
// 这里就可以过滤掉哪些没有加注解的方法
AspectJExpressionPointcut expressionPointcut = getPointcut(
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
// 这里就是构造一个InstantiationModelAwarePointcutAdvisor,这个在前面的Advisor体系中提到过
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
创建代理的相关方法
wrapIfNecessary方法
这个方法的主要作用就是判断bean是否需要创建代理,如果需要,则调用createProxy来创建代理
// ==========AbstractAutoProxyCreator==========
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return 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;
}
// 这里是找到可以用在该bean中的所有advisor,如果不为空,就为其创建代理
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;
}
// ==========AbstractAdvisorAutoProxyCreator==========
protected 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();
}
// ==========AbstractAdvisorAutoProxyCreator==========
/**
可以看到找的流程也很熟悉
1. 首先找到所有的Advisor,也是通过findCandidateAdvisors方法实现的
2. 遍历所有的Advisor,看它是否能用在这个这个Bean上
具体而言,前面提过,对于注解开发的Advisor,返回的都是
InstantiationModelAwarePointcutAdvisor,而它就是一个PointcutAdvisor
对于PointcutAdvisor,会有一个Pointcut用来匹配一个类是否应该被代理
详细信息可以回顾一下前面的Pointcut,这里简单说明
Pointcut有两个层次的匹配,类级别的匹配和方法级别的匹配,所以这里的逻辑就是:
1. 首先尝试用类匹配器匹配类,如果匹配不上,该类不需要代理,否则使用方法匹配器继续
2. 遍历目标类所有的方法,用方法匹配器匹配,只要有一个匹配上了,就说明该目标类需要代理
需要留意的是,在进行方法匹配时,会将目标类的父类方法和接口方法都匹配一遍
**/
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;
}
createProxy方法
最后就是创建代理了
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
/**
这里判断是否采用CGLIB代理,判断的方式是:
从beanDefinition中查看是否有属性名为org.springframework.aop.framework.autoproxy.AutoProxyUtils.preserveTargetClass
且其值为true的
**/
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
/**
构建advisors,准确的说应该是合并
auto-proxy-creator中可以指定拦截器(Advisor),这些拦截器应该作用到所有的代理类中
这里就是将公共的拦截器与目标类的特定拦截器合并,然后创建代理
**/
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
// 这是一个空方法,以后可以来扩展它
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 最后创建代理返回
return proxyFactory.getProxy(classLoader);
}