Spring的Aop原理和实现

BeanPostProcessor

BeanPostProcessor是一个后置处理器,用于在所有bean初始化前后进行一些处理工作;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.springframework.beans.factory.config;

import org.springframework.beans.BeansException;
import org.springframework.lang.Nullable;

public interface BeanPostProcessor {
//在Bean初始化之前调用
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
//在Bean初始化之后调用
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}

BeanPostProcessorspring底层中大量使用,比如我们需要获取ApplicationContext时,需要实现ApplicationContextAware接口

1
2
3
public interface ApplicationContextAware extends Aware {
void setApplicationContext(ApplicationContext arg0) throws BeansException;
}

那么setApplicationContext在什么时候调用呢?spring底层有一个ApplicationContextAwareProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
private final StringValueResolver embeddedValueResolver;

public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
this.applicationContext = applicationContext;
this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
}

@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
//1.判断Bean是否实现了Aware接口,否则直接返回bean
if (!(bean instanceof EnvironmentAware) && !(bean instanceof EmbeddedValueResolverAware)
&& !(bean instanceof ResourceLoaderAware) && !(bean instanceof ApplicationEventPublisherAware)
&& !(bean instanceof MessageSourceAware) && !(bean instanceof ApplicationContextAware)) {
return bean;
} else {
AccessControlContext acc = null;
if (System.getSecurityManager() != null) {
acc = this.applicationContext.getBeanFactory().getAccessControlContext();
}

if (acc != null) {
AccessController.doPrivileged(() -> {
this.invokeAwareInterfaces(bean);
return null;
}, acc);
} else {
//调用Aware实现的方法
this.invokeAwareInterfaces(bean);
}

return bean;
}
}

private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}

if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}

if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}

if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}

if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
//实现了ApplicationContextAware接口时,调用其实现的setApplicationContext方法
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}

可以看到,spring源码中通过BeanPostProcessor接口,在容器自动装配bean的之前,对实现了ApplicationContextAware接口的bean进行了方法回调。

那么BeanPostProcessor接口又是在什么时候被调用的呢?通过跟踪源码调用链得知,当一个bean被初始化时,会调用AbstractBeanFactorydoGetBean方法,该方法中将会调用AbstractAutowireCapableBeanFactorydoCreateBean方法,以下是摘取部分doCreateBean方法:

1
2
3
4
5
6
7
8
9
10
11
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
/* 省略部分代码 */
try {
//给Bean的属性赋值
this.populateBean(beanName, mbd, instanceWrapper);
exposedObject = this.initializeBean(beanName, exposedObject, mbd);
} catch (Throwable arg17) {
/* 省略部分代码 */
}
/* 省略部分代码 */
}

从源码看到它先调用populateBean方法给刚创建好的bean对象进行属性赋值,然后调用initializeBean方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
/* 省略部分代码 */
//Bean的实例已经创建好了
Object wrappedBean = bean;
if(mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessor后置处理器的Before方法
wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
}

try {
//执行初始化方法(如@PostConstruct方法)
this.invokeInitMethods(beanName, wrappedBean, mbd);

} catch (Throwable arg5) {
throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", arg5);
}
if(mbd == null || !mbd.isSynthetic()) {
//调用BeanPostProcessor后置处理器的After方法
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;

Object current;
for (Iterator arg3 = this.getBeanPostProcessors().iterator(); arg3.hasNext(); result = current) {
BeanPostProcessor processor = (BeanPostProcessor) arg3.next();
current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
}

return result;
}

可以看到在initializeBean中调用了applyBeanPostProcessorsBeforeInitialization,该方法中将遍历容器中所有的BeanPostProcessor;挨个执行beforeInitialization方法,一但返回null,则跳出循环,不会执行后面的BeanPostProcessor.postProcessorsBeforeInitialization

applyBeanPostProcessorsAfterInitialization方法也和上文的方法中相似,也就是说,在初始化bean的过程中,其调用顺序如下:

populateBean(); //给Bean的属性赋值

initializeBean {

​ applyBeanPostProcessorsBeforeInitialization(bean, beanName); //Bean初始化之前调用

​ invokeInitMethods(beanName, wrappedBean, mbd); //执行自定义初始化

​ postProcessBeforeInitialization(result, beanName); //Bean初始化之后调用

}

Spring底层大量使用了BeanPostProcessor接口,比如我们的@Init@destory,该注解工作的原理在于InitDestroyAnnotationBeanPostProcessor类,通过BeanPostProcessor的特性,扫描Bean的注解和方法,判断是否包含@Init@destory注解,如果有,则进行方法反射调用。

还有如@Autowired@PostConstruct,都是有其对应的XXXBeanPostProcessor接口。

Aware

自定义组件想要使用Spring容器底层的一些组件(ApplicationContext,BeanFactory,xxx),可以通过实现xxxAware,在创建对象时,会调用接口规定的方法注入相关组件。

1
2
public interface Aware {
}

aop-01

ApplicationContextAware,对应ApplicationContextAwareProcessor

AOP

概念

AOP:【动态代理】

指在程序运行期间动态的将某段代码切入到指定方法指定位置进行运行的编程方式;

1、导入aop模块;Spring AOP:(spring-aspects)

2、定义一个业务逻辑类(MathCalculator);在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)

3、定义一个日志切面类(LogAspects):切面类里面的方法需要动态感知MathCalculator.div运行到哪里然后执行;

通知方法:

  • 前置通知(@Before):logStart:在目标方法(div)运行之前运行
  • 后置通知(@After):logEnd:在目标方法(div)运行结束之后运行(无论方法正常结束还是异常结束)
  • 返回通知(@AfterReturning):logReturn:在目标方法(div)正常返回之后运行
  • 异常通知(@AfterThrowing):logException:在目标方法(div)出现异常以后运行
  • 环绕通知(@Around):动态代理,手动推进目标方法运行(joinPoint.procced())

4、给切面类的目标方法标注何时何地运行(通知注解);

5、将切面类和业务逻辑类(目标方法所在类)都加入到容器中;

6、必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)

7、给配置类中加 @EnableAspectJAutoProxy 【开启基于注解的aop模式】

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/**
* 切面类
* @Aspect: 告诉Spring当前类是一个切面类
*/
@Aspect
public class LogAspects {

//抽取公共的切入点表达式
//1、本类引用
//2、其他的切面引用
@Pointcut("execution(public int com.MathCalculator.*(..))")
public void pointCut(){};

//@Before在目标方法之前切入;切入点表达式(指定在哪个方法切入)
@Before("pointCut()")
public void logStart(JoinPoint joinPoint){
Object[] args = joinPoint.getArgs();
System.out.println(""+joinPoint.getSignature().getName()+"运行。。。@Before:参数列表是:{"+Arrays.asList(args)+"}");
}

//方法不在本类中直接使用类路径
@After("com.LogAspects.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
}

//JoinPoint一定要出现在参数表的第一位,returning设置接受返回值参数
@AfterReturning(value="pointCut()",returning="result")
public void logReturn(JoinPoint joinPoint,Object result){
System.out.println(""+joinPoint.getSignature().getName()+"正常返回。。。@AfterReturning:运行结果:{"+result+"}");
}

//设置接受返回值参数
@AfterThrowing(value="pointCut()",throwing="exception")
public void logException(JoinPoint joinPoint,Exception exception){
System.out.println(""+joinPoint.getSignature().getName()+"异常。。。异常信息:{"+exception+"}");
}
}
1
2
3
4
5
6
public class MathCalculator {
public int div(int i,int j){
System.out.println("MathCalculator...div...");
return i/j;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {

//业务逻辑类加入容器中
@Bean
public MathCalculator calculator(){
return new MathCalculator();
}

//切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
1
2
3
4
5
6
7
8
9
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);

MathCalculator bean = applicationContext.getBean(MathCalculator.class);
bean.div(1, 2);
applicationContext.close();
}
}

总结:

1、将业务逻辑组件和切面类都加入到容器中;告诉Spring哪个是切面类(@Aspect)

2、在切面类上的每一个通知方法上标注通知注解,告诉Spring何时何地运行(切入点表达式)

3、开启基于注解的aop模式;@EnableAspectJAutoProxy

原理

学习AOP原理的方向:【看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?】

@EnableAspectJAutoProxy注解是什么呢?

先了解这个ImportBeanDefinitionRegistrar接口的功能:

1
2
3
4
5
6
7
8
9
public interface ImportBeanDefinitionRegistrar {
default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
BeanNameGenerator importBeanNameGenerator) {
this.registerBeanDefinitions(importingClassMetadata, registry);
}

default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}

它的作用是通过实现ImportBeanDefinitionRegistrar接口的方法,创建自定义的对象和BeanDefinetion对象并设置相关属性,然后将BeanDefinetion注册到BeanDefinitionRegistry中,完成Bean对象的注册。


回过头来看看@EnableAspectJAutoProxy注解

1
2
3
4
5
6
7
8
9
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({AspectJAutoProxyRegistrar.class})
public @interface EnableAspectJAutoProxy {
boolean proxyTargetClass() default false;

boolean exposeProxy() default false;
}

可以看到有注解@Import({AspectJAutoProxyRegistrar.class})该注解的作用是给容器中导入AspectJAutoProxyRegistrar,利用AspectJAutoProxyRegistrar自定义给容器中注册bean

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册一个bean对象
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata,
EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}

if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}

那么它注册了什么Bean呢?

接着跟踪AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);,将会调用该方法

1
2
3
4
5
6
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,
@Nullable Object source) {
//注册Bean或者更新Bean--->AnnotationAwareAspectJAutoProxyCreator
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//如果容器中已经包含internalAutoProxyCreator,则升级该对象
if (registry.containsBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator")) {
BeanDefinition beanDefinition1 = registry
.getBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator");
if (!cls.getName().equals(beanDefinition1.getBeanClassName())) {
int currentPriority = findPriorityForClass(beanDefinition1.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
beanDefinition1.setBeanClassName(cls.getName());
}
}

return null;
} else {
//如果容器中没有包含internalAutoProxyCreator,则创建该Bean
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Integer.valueOf(Integer.MIN_VALUE));
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;
}
}

也就是说,AspectJAutoProxyRegistrar类给容器中注册了一个BeanName等于internalAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator对象(注解装配模式的切面自动代理创建器)。


AnnotationAwareAspectJAutoProxyCreator是个什么对象呢?

先分析一下它的继承关系

aop-03

1
2
3
4
5
6
7
8
9
10
11
12
13
AnnotationAwareAspectJAutoProxyCreator:
-> extends AspectJAwareAdvisorAutoProxyCreator
-> extends AbstractAdvisorAutoProxyCreator
-> extends AbstractAutoProxyCreator
-> implements SmartInstantiationAwareBeanPostProcessor
-> implements BeanFactoryAware
-> extends ProxyProcessorSupport

ProxyProcessorSupport
-> extends ProxyConfig
-> implements Ordered
-> implements BeanClassLoaderAware
-> implements AopInfrastructureBean

程序启动时,会先调度AbstractApplicationContext的刷新容器方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();

// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);

try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);

// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
//3、注册bean的后置处理器
registerBeanPostProcessors(beanFactory);

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

//4、完成BeanFactory初始化工作;创建剩下的单实例bean
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
finishRefresh();
}

catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}

// Destroy already created singletons to avoid dangling resources.
destroyBeans();

// Reset 'active' flag.
cancelRefresh(ex);

// Propagate exception to caller.
throw ex;
}

finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}

可以看到其中有一个方法是registerBeanPostProcessors,用来注册Bean的后置处理器

1
2
3
4
5
6
7
8
/**
* Instantiate and register all BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
//3.1、获取IOC容器已经定义了的需要创建对象的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);

// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
//3.2、给容器中加别的BeanPostProcessor
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

// 分离BeanPostProcessor,判断是否实现PriorityOrdered extends Ordered接口,进行优先级的排序
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

//3.3、优先注册实现了PriorityOrdered接口的BeanPostProcessor
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

//3.4、再给容器中注册实现了Ordered接口的BeanPostProcessor;
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
//AnnotationAwareAspectJAutoProxyCreator实现了Ordered接口,将在这里调度getBean创建对象
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
//按照优先级排序
sortPostProcessors(orderedPostProcessors, beanFactory);
//3.5、注册到BeanFactory工厂中
registerBeanPostProcessors(beanFactory, orderedPostProcessors);

//3.6、注册没实现优先级接口的BeanPostProcessor;
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);

// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}

在第一步的注释位置断点,可以看到所有已经定义了的需要创建对象的后置处理器包含了org.springframework.aop.config.internalAutoProxyCreator的Bean名称

aop-02

由于AnnotationAwareAspectJAutoProxyCreator类最终实现了Ordered接口,将调用getBean方法创建对象

1
2
3
4
@Override
public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return doGetBean(name, requiredType, null, false);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
/**
* Return an instance, which may be shared or independent, of the specified bean.
* @param name the name of the bean to retrieve
* @param requiredType the required type of the bean to retrieve
* @param args arguments to use when creating a bean instance using explicit arguments
* (only applied when creating a new instance as opposed to retrieving an existing one)
* @param typeCheckOnly whether the instance is obtained for a type check,
* not for actual use
* @return an instance of the bean
* @throws BeansException if the bean could not be created
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(
String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
throws BeansException {
//4.2.1、先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则再创建;
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
/* 省略部分代码 */
}
else {
// Create bean instance.
if (mbd.isSingleton()) {
//当IOC容器第一次获取Bean的单实例时,获取不到,将创建Bean
sharedInstance = getSingleton(beanName, () -> {
try {
//3.4 创建Bean实例并且返回
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
/* 省略部分代码 */
}
});
/* 省略部分代码 */
}
}
/* 省略部分代码 */
}

接下来分析一下创建Bean实例的过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

/* 省略部分代码 */
try {
// 给后置处理器一个机会来创建一个代理对象替代目标实例
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
//3.4 调用doCreateBean创建实例
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
/* 省略部分代码 */
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {

// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//3.4.1、创建Bean的实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}

/* 省略部分代码 */

//Bean的实例已经创建成功
// Initialize the bean instance.
Object exposedObject = bean;
try {
//3.4.2、给Bean的属性赋值
populateBean(beanName, mbd, instanceWrapper);
//3.4.3 初始化bean;
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
/* 省略部分代码 */
}
/* 省略部分代码 */
return exposedObject;
}

进一步分析initializeBean方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
//3.4.3.1、处理Aware接口的方法回调,将会回调实现BeanFactoryAware接口的setBeanFactory方法

invokeAwareMethods(beanName, bean);
}

Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
//3.4.3.2、执行后置处理器的postProcessBeforeInitialization()
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

try {
//3.4.3.3、执行自定义的初始化方法
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
//3.4.3.4、执行后置处理器的postProcessAfterInitialization()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}

进一步观看它是如何处理Aware接口的方法回调的,invokeAwareMethods方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
//实现了BeanFactoryAware接口的类,将会调用setBeanFactory方法
//将会调用实现类的AbstractAdvisorAutoProxyCreator.setBeanFactory方法
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}

也就是说,invokeAwareMethods方法将会调用实现类实现的BeanFactoryAware.setBeanFactory(),通过之前的继承树分析,AnnotationAwareAspectJAutoProxyCreator实现了BeanFactoryAware接口。

1
2
3
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory arg0) throws BeansException;
}

观察AnnotationAwareAspectJAutoProxyCreator类的链路的setBeanFactory实现关系:

1
2
3
4
5
AbstractAutoProxyCreator.setBeanFactory();
//父类复写setBeanFactory方法,内部调用AbstractAdvisorAutoProxyCreator.initBeanFactory方法
AbstractAdvisorAutoProxyCreator.setBeanFactory(); -> initBeanFactory();
//父类复写initBeanFactory方法
AnnotationAwareAspectJAutoProxyCreator.initBeanFactory方法();

通过分析链路调用,最终将会调用AbstractAdvisorAutoProxyCreator.setBeanFactory方法

1
2
3
4
5
6
7
8
9
10
public void setBeanFactory(BeanFactory beanFactory) {
super.setBeanFactory(beanFactory);
if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
throw new IllegalArgumentException(
"AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
} else {
//将调用子类的AnnotationAwareAspectJAutoProxyCreator.initBeanFactory
this.initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}
}

initBeanFactory方法被子类复写,最终调用了AnnotationAwareAspectJAutoProxyCreator.initBeanFactory方法

1
2
3
4
5
6
7
8
9
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
//创建了反射的AspectJ通知工厂
if (this.aspectJAdvisorFactory == null) {
this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
}
//创建了AspectJ通知构建器的适配器
this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(this, beanFactory, this.aspectJAdvisorFactory);
}

以上是创建和注册AnnotationAwareAspectJAutoProxyCreator的过程,接下来分析创建完Bean实例后逻辑。


回过头来接着看AbstractApplicationContext.refresh方法的第四步注释:

1
2
3
4
5
6
7
8
9
10
11
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
/* 省略部分代码 */

// 4.完成BeanFactory初始化工作;创建剩下的单实例bean
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public void preInstantiateSingletons() throws BeansException {
/* 省略部分代码 */
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
/* 省略部分代码 */
}
else {
//4.2 创建容器中未被创建的Bean对象
getBean(beanName);
}
}
}
/* 省略部分代码 */
}

这时候再回到上文的getBean方法,重新回顾它的调用链:

1
2
3
4
5
6
7
8
getBean:
-> doGetBean()
#先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用
-> getSingleton()
#否则再调用createBean方法创建
-> createBean()
-> resolveBeforeInstantiation()
-> doCreateBean()

Spring就是在这里保证了单实例的Bean只被创建一次,只要创建好的Bean都会被缓存起来;

createBean创建Bean的过程中,会先调用resolveBeforeInstantiation方法,该方法的作用是给后置处理器一个机会来创建一个代理对象替代目标实例,如果能返回代理对象就使用,如果不能就将调用doCreateBean创建Bean实例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Nullable
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
Object bean = null;
if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
// Make sure bean class is actually resolved at this point.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
//后置处理器先尝试返回对象;
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
//如果对象不为空,则调用BeanPostProcessor.postProcessAfterInitialization
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}

进一步分析applyBeanPostProcessorsBeforeInstantiation方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断BeanPostProcessor是否为InstantiationAwareBeanPostProcessor类型
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}

根据上文的继承关系分析得知,AnnotationAwareAspectJAutoProxyCreator的父类实现了SmartInstantiationAwareBeanPostProcessor接口

1
2
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor{
}
1
2
3
4
5
6
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
}

所以可以得出结论,最终会在这里调用AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator实现的postProcessBeforeInstantiation方法,用来尝试创建代理对象替代目标对象。

值得注意的是,InstantiationAwareBeanPostProcessorBeanPostProcessor不太一样。

BeanPostProcessor.postProcessBeforeInitialization:是在Bean对象创建完成初始化前后调用的
InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation:是在创建Bean实例之前先尝试用后置处理器返回对象的

它们的调用时机不同,并且它们的方法名不同,一个是Initialization,另一个是Instantiation

所以能够得到一个结论,AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前会有一个拦截,会先调用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation(),先尝试返回bean的代理实例。


接下来了解InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
Object cacheKey = getCacheKey(beanClass, beanName);

if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
//1.判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
//2.判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean 或者是否是切面(@Aspect)
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
}

// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
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;
}

isInfrastructureClass方法是用来判断该Bean是否是切面的基础类型

1
2
3
4
5
6
7
8
9
10
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复写了该方法,增加了一个@Aspect注解的切面判断:

1
2
3
4
5
6
@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
//检测父类实现的基础类型判断和Aspect注解判断
return (super.isInfrastructureClass(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
1
2
3
4
@Override
public boolean isAspect(Class<?> clazz) {
return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
}

shouldSkip方法用来判断是否跳过当前Bean

1
2
3
4
5
6
7
8
9
10
11
12
13
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
// 获取候选的增强器(切面里面的通知方法)
// 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);
}
1
2
3
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}

跟踪源码后,最终InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()尝试创建代理对象失败,将调用doCreateBean创建普通实例,最终会在initializeBean()方法中,调用BeanPostProcessor后置处理器的实现。

由于AbstractAutoProxyCreator类实现了postProcessAfterInitialization方法,所以将被调用。

1
2
3
4
5
6
7
8
9
10
11
@Override
public 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;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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;
}
//判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean 或者是否是切面(@Aspect)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
// Create proxy if we have advice.
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
//保存当前bean在advisedBeans中;表示当前Bean已经被增强处理
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//如果当前bean需要增强,创建当前bean的代理对象;
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;
}

进一步分析getAdvicesAndAdvisorsForBean方法

1
2
3
4
5
6
7
8
9
10
11
@Override
@Nullable
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();
}
1
2
3
4
5
6
7
8
9
10
11
12
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//获取所有候选的增强器
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//找到可以应用在当前Bean的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
//给增强器排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
1
2
3
4
5
6
7
8
9
10
11
12
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//最后调用AOP的工具类进行pointCut的match操作
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}

回到wrapIfNecessary方法,当获取到的advisors增强器不为空时,将调用createProxy创建代理对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
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);

if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//获取所有应用在当前Bean的增强器(通知方法)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
//保存到proxyFactory
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);

proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
//用代理工厂创建对象
return proxyFactory.getProxy(getProxyClassLoader());
}

进一步分析proxyFactory.getProxy(getProxyClassLoader());是怎么通过代理工厂创建代理对象的

1
2
3
public Object getProxy(@Nullable ClassLoader classLoader) {
return createAopProxy().getProxy(classLoader);
}
1
2
3
4
5
6
protected final synchronized AopProxy createAopProxy() {
if (!this.active) {
activate();
}
return getAopProxyFactory().createAopProxy(this);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
//Spring支持两种代理模式:由spring自行决定
//当Bean实现了接口时,使用jdk动态代理,否则使用Cglib动态代理,可以强制设置使用cglib动态代理
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
//创建JDK的动态代理
return new JdkDynamicAopProxy(config);
}
//创建Cglib的动态代理
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}

由于我们没有实现接口,所以spring选择了创建Cglib动态代理对象,容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);

aop-05

比如可以看到存储在代理对象中的通知方法、切入方法、切入时机等等信息

aop-06

接着进下一步执行的方法,可以看到cglib动态代理对象执行了intercept方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
//要切入的目标对象
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//根据ProxyFactory对象获取将要执行的目标方法拦截器链;
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;

// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
//如果没有拦截器链,直接执行目标方法;
retVal = methodProxy.invoke(target, argsToUse);
}
else {
//如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个 CglibMethodInvocation 对象
//并调用 Object retVal = CglibMethodInvocation.proceed();
// We need to create a method invocation...
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal);
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}

看看他是怎么调用方法生成拦截器链的

1
2
3
4
5
6
7
8
9
10
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);
this.methodCache.put(cacheKey, cached);
}
return cached;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {

// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
//能够应用在目标方法的增强器(而不是容器中的所有增强器)
Advisor[] advisors = config.getAdvisors();
//创建一个List保存目标方法的所有拦截器,为它赋予初始化长度:5
//一个默认的ExposeInvocationInterceptor 和 (LogAspects)4个自定义增强器;
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//遍历增强器,将其转为Interceptor;
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
match = mm.matches(method, actualClass);
}
if (match) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}

return interceptorList;
}

可以看到,生成了一条拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//如果是MethodInterceptor,直接加入到集合中
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
//如果不是,使用AdvisorAdapter将增强器转为MethodInterceptor;
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
//转换完成返回MethodInterceptor数组;
return interceptors.toArray(new MethodInterceptor[0]);
}

aop-09

aop-07

最终可以看到如上图,有5个拦截器,其中一个是spring自带的ExposeInvocationInterceptor,而AspectJAfterAdviceAspectJAfterThrowingAdviceMethodInterceptor接口,直接添加到了拦截器中,剩下的则被AdvisorAdapter转换成MethodInterceptor


以上就是拦截器链链的创建过程,回到intercept方法,当拦截器链创建成功之后,若存在拦截器链,将调用CglibMethodInvocation.proceed()方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
private int currentInterceptorIndex = -1;

@Override
@Nullable
public Object proceed() throws Throwable {
//如果没有拦截器执行执行目标方法,或者拦截器的索引和拦截器数组-1大小一样(指定到了最后一个拦截器)执行目标方法;
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//利用反射执行目标方法
return invokeJoinpoint();
}
//按照索引自增先获取第【0】个拦截器ExposeInvocationInterceptor,然后调用拦截器的invoke方法
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {

return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}

根据逻辑分析,最开始的时候currentInterceptorIndex= -1,然后执行++currentInterceptorIndex = 0,并获取下标【0】的拦截器,也就是ExposeInvocationInterceptor,并执行它的invoke方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//ExposeInvocationInterceptor类
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//invocation是一个ThreadLocal对象,用于多个线程共享同一个【MethodInvocation】对象
MethodInvocation oldInvocation = invocation.get();
invocation.set(mi);
try {
//再次调用MethodInvocation.proceed()方法
return mi.proceed();
}
finally {
invocation.set(oldInvocation);
}
}

这时候,再次调用了proceed方法,由于currentInterceptorIndex = 0,再次执行++currentInterceptorIndex,所以将获取下标【1】的拦截器MethodBeforeAdviceInterceptor并执行它的invoke方法

1
2
3
4
5
6
7
//MethodBeforeAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
//先调用Before增强器
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
1
2
3
4
5
6
7
8
9
10
11
12
//AspectJAfterAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//先接着链式调用拦截器链
return mi.proceed();
}
finally {
//不管是否返回异常,调用After增强器
invokeAdviceMethod(getJoinPointMatch(), null, null);
}
}
1
2
3
4
5
6
7
8
9
//AfterReturningAdviceInterceptor
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
////先接着链式调用拦截器链
Object retVal = mi.proceed();
//获取返回值,调用return增强器
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//AspectJAfterThrowingAdvice
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
try {
//这时候调用proceed时,将满足currentInterceptorIndex = interceptors.size - 1,调用目标方法
return mi.proceed();
}
catch (Throwable ex) {
//trycatch中处理Exception增强器
if (shouldInvokeOnThrowing(ex)) {
invokeAdviceMethod(getJoinPointMatch(), null, ex);
}
throw ex;
}
}

以上就是Spring的Aop工作原理过程,具体调用链如下图:

aop-10

流程

aop-04

AOP的切入过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#1.传入配置类,创建IOC容器
#2.注册配置类,调用refresh() 刷新容器
AbstractApplicationContext.refresh()
#3.注册Bean的后置处理器来方便拦截bean的创建
-> registerBeanPostProcessors(beanFactory)
#3.1 获取IOC容器已经定义了的需要创建对象的所有BeanPostProcessor
-> beanFactory.getBeanNamesForType(BeanPostProcessor)
#3.2 给容器中加别的BeanPostProcessor
-> beanFactory.addBeanPostProcessor(BeanPostProcessor)
#3.3 优先注册实现了PriorityOrdered接口的BeanPostProcessor
#3.4 再给容器中注册实现了Ordered接口的BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)
# 实际上就是创建BeanPostProcessor对象,保存在容器中;
-> beanFactory.getBean()
-> doGetBean()
-> createBean()
-> doCreateBean()
#3.4.1 创建Bean的实例
-> createBeanInstance()
#3.4.2 给bean的各种属性赋值
-> populateBean()
#3.4.3 初始化bean
-> initializeBean()
#3.4.3.1 处理Aware接口的方法回调,回调实现BeanFactoryAware类的setBeanFactory方法
-> invokeAwareMethods()
#回调AbstractAdvisorAutoProxyCreator实现的setBeanFactory方法
-> AbstractAdvisorAutoProxyCreator.setBeanFactory(beanFactory)
#调用子类重写的initBeanFactory方法
-> AnnotationAwareAspectJAutoProxyCreator.initBeanFactory(beanFactory)
#3.4.3.2 执行后置处理器的postProcessBeforeInitialization()
-> applyBeanPostProcessorsBeforeInitialization()
-> BeanPostProcessor.postProcessBeforeInitialization()
#3.4.3.3 执行自定义的初始化方法 如:@PostConstruct、@Init
-> invokeInitMethods()
#3.4.3.4 执行后置处理器的postProcessAfterInitialization()
-> applyBeanPostProcessorsAfterInitialization()
-> BeanPostProcessor.postProcessAfterInitialization()
#3.5 把创建成功的BeanPostProcessor注册到BeanFactory中
-> beanFactory.addBeanPostProcessor(postProcessor)
#3.6 注册没实现优先级接口的BeanPostProcessor

#4.完成BeanFactory初始化工作;创建剩下的单实例bean
-> finishBeanFactoryInitialization(beanFactory)
-> preInstantiateSingletons()
#4.1 遍历获取容器中所有定义的的Bean信息
-> beanNames.iterator()
#4.2 创建容器中未被创建的Bean对象
-> beanFactory.getBean()
-> doGetBean()
#4.2.1 先从缓存中获取当前bean,如果能获取到,说明bean是之前被创建过的,直接使用,否则调用createBean()创建
# Spring就是在这里保证了单实例的Bean只被创建一次,只要创建好的Bean都会被缓存起来
-> getSingleton(beanName)
#4.2.2 真正创建一个Bean
-> createBean()
#【AnnotationAwareAspectJAutoProxyCreator】会在这个方法对所有bean创建之前有一个拦截,尝试返回代理对象
#解析BeforeInstantiation,给后置处理器一个机会来创建一个代理对象替代目标实例
#如果能返回代理对象就使用,如果不能就将调用doCreateBean创建Bean实例
-> resolveBeforeInstantiation(beanName, mbdToUse)
#后置处理器先尝试返回代理对象
-> applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)
#拿到所有后置处理器,如果是InstantiationAwareBeanPostProcessor;
#就执行postProcessBeforeInstantiation
#【AnnotationAwareAspectJAutoProxyCreator】的父类【AbstractAutoProxyCreator】实现了该方法
-> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
#返回的代理对象不为空,则调用
-> applyBeanPostProcessorsAfterInitialization(bean, beanName)
-> BeanPostProcessor.postProcessAfterInitialization()
#3.3.x 流程相同
-> doCreateBean()

动态代理对象的创建过程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
createBean():
-> resolveBeforeInstantiation(beanName, mbdToUse)
-> applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)
#【AbstractAutoProxyCreator】实现该方法,尝试拦截失败则将调用【doCreateBean】
-> InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()
#1.判断当前bean是否在advisedBeans中(保存了所有需要增强bean)
#2.判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean 或者是否是切面(@Aspect)
# 实际上是调用了【AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass()】
-> isInfrastructureClass()
-> AbstractAutoProxyCreator.isInfrastructureClass()
-> AspectJAdvisorFactory.isAspect()
#3.是否需要跳过 实际上调用【AspectJAwareAdvisorAutoProxyCreator.shouldSkip()】
-> shouldSkip()
#获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
#每一个封装的通知方法的增强器是 【InstantiationModelAwarePointcutAdvisor】
#判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
-> findCandidateAdvisors();
-> super.shouldSkip()

#尝试拦截失败,调用【创建普通对象实例】的方法
-> doCreateBean()
-> createBeanInstance()
-> populateBean()
-> initializeBean()
-> invokeAwareMethods()
-> applyBeanPostProcessorsBeforeInitialization()
-> BeanPostProcessor.postProcessBeforeInitialization()
-> invokeInitMethods()
-> applyBeanPostProcessorsAfterInitialization()
#执行【AbstractAutoProxyCreator】实现的postProcessAfterInitialization()
-> BeanPostProcessor.postProcessAfterInitialization()
#在需要的时候进行包装
-> wrapIfNecessary(bean, beanName, cacheKey)
#获取当前bean的所有增强器(通知方法) Object[] specificInterceptors
-> getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
-> findEligibleAdvisors()
#找到候选的所有的增强器
-> findCandidateAdvisors();
#找到可以应用在当前Bean的增强器(找哪些通知方法是需要切入当前bean方法的)
-> findAdvisorsThatCanApply()
#给增强器排序
-> sortAdvisors()
#保存当前bean在advisedBeans中;
#如果当前bean需要增强,创建当前bean的代理对象;
-> createProxy()
#获取所有应用在当前Bean的增强器(通知方法)
-> buildAdvisors()
#保存到proxyFactory
-> proxyFactory.addAdvisors()
#用代理工厂创建对象
-> proxyFactory.getProxy(getProxyClassLoader());
#创建代理对象,Spri oxy(config);jdk动态代理;
#ObjenesisCglibAopProxy(config);cglib的动态代理;
-> createAopProxy(AdvisedSupport config)
#给容器中返回当前组件使用cglib增强了的代理对象;
#以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;

动态代理的拦截(目标方法执行)过程:

aop-08

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器,目标对象,xxx);
#1.通过调用CglibAopProxy.intercept()拦截目标方法的执行
CglibAopProxy.intercept()
#2.根据ProxyFactory对象获取将要执行的目标方法拦截器链;
-> ProxyFactory.getInterceptorsAndDynamicInterceptionAdvice()
-> AdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
#2.1 获取应用在目标方法的所有增强器
#2.2 创建拦截器集合【List<Object> interceptorList】并赋予长度
#2.3 遍历所有增强器,将其转化为【Interceptor】
#2.4 如果是【MethodInterceptor】,直接加入到集合中
# 如果不是,使用【AdvisorAdapter】将增强器转为MethodInterceptor;
-> AdvisorAdapterRegistry.getInterceptors(advisor);
#3.如果没有拦截器链,直接执行目标方法;
-> methodProxy.invoke(target, argsToUse);
#4.如果有拦截器链,把需要执行的目标对象,目标方法,
# 拦截器链等信息传入创建一个 CglibMethodInvocation 对象

#【拦截器链的触发过程】;
-> CglibMethodInvocation.proceed()
#获取index=【0】的拦截器
-> ExposeInvocationInterceptor.invoke()
#获取index=【1】的拦截器
-> MethodBeforeAdviceInterceptor.invoke()
#调用before增强器
-> MethodBeforeAdvice.before()
#获取index=【2】的拦截器
-> AspectJAfterAdvice.invoke()
#获取index=【3】的拦截器
-> AfterReturningAdviceInterceptor.invoke()
#获取Index=【4】的拦截器
-> AspectJAfterThrowingAdvice.invoke()
#执行目标方法
-> invokeJoinpoint()
#如果抛异常,则调用exception增强器
-> invokeAdviceMethod()
#如果不抛异常,调用return增强器
-> AfterReturningAdvice.afterReturning()
#调用after增强器
-> invokeAdviceMethod()

总结

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
1.@EnableAspectJAutoProxy 开启AOP功能
2.@EnableAspectJAutoProxy 会给容器中注册一个组件AnnotationAwareAspectJAutoProxyCreator
3.AnnotationAwareAspectJAutoProxyCreator是一个后置处理器;
4.容器的创建流程:
1.registerBeanPostProcessors()注册后置处理器;创建AnnotationAwareAspectJAutoProxyCreator对象
2.finishBeanFactoryInitialization()初始化剩下的单实例bean
1.创建业务逻辑组件和切面组件
2.AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程
3.组件创建完之后,判断组件是否需要增强
是:切面的通知方法,包装成增强器(Advisor);给业务逻辑组件创建一个代理对象(cglib);
否:创建普通Bean实例
5.执行目标方法:
1.代理对象执行目标方法
2.CglibAopProxy.intercept();
1.得到目标方法的拦截器链(增强器包装成拦截器MethodInterceptor)
2.利用拦截器的链式机制,依次进入每一个拦截器进行执行;
3.效果:
正常执行:前置通知-》目标方法-》后置通知-》返回通知
出现异常:前置通知-》目标方法-》后置通知-》异常通知

“本篇文章主要摘自参考资料

最后更新: 2020年11月02日 09:13

原始链接: https://midkuro.gitee.io/2020/10/20/spring-aop/

× 请我吃糖~
打赏二维码