1.AOP解释
摘自百度百科
AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2.如何使用SpringAOP
准备工作
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 | @Aspect |
配置类
1 | @EnableAspectJAutoProxy |
业务逻辑类
1 | public class MathCalculator { |
测试类
1 | public class IOCTest_AOP { |
结果
3.@EnableAspectJAutoProxy到底干了啥?
开启SrpingAOP功能时,有使用一个注解为@EnableAspectJAutoProxy,查看该注解时,可以看到这个注解Import了一个类
跟进这个类,可以看到他是继承了ImportBeanDefinitionRegistrar,并且实现了ImportBeanDefinitionRegistrar的registerBeanDefinitions()方法,为了是导入自定义组件
再跟进这个方法
整个@EnableAspectJAutoProxy注解作用就是为了注册一个id为org.springframework.aop.config.internalAutoProxyCreator
,class为AnnotationAwareAspectJAutoProxyCreator.class
的BeanDefinition
AnnotationAwareAspectJAutoProxyCreatord结构
在它的所有父类接口中,有一个抽象类AbstractAutoProxyCreator
继承了:ProxyProcessorSupport类
实现了:SmartInstantiationAwareBeanPostProcessor和BeanFactoryAware接口
具体类图如下:
主要为了说明类之间的继承关系,方法的返回值和参数未在图中列出
这里,我们要重点关注两个实现
- SmartInstantiationAwareBeanPostProcessor:后置处理器(在我们bean初始化完成前后要做的事情)
postProcessBeforeInstantiation()和postProcessAfterInstantiation()两个方法做了什么事? - AbstractAdvisorAutoProxyCreator重写的setBeanFactory()做了什么事?
- AnnotationAwareAspectJAutoProxyCreator的initBeanFactory做了什么事?
重点:AnnotationAwareAspectJAutoProxyCreator这个类是贯穿SpringAOP整个功能的类
重点:AnnotationAwareAspectJAutoProxyCreator这个类是贯穿SpringAOP整个功能的类
重点:AnnotationAwareAspectJAutoProxyCreator这个类是贯穿SpringAOP整个功能的类
4 Spring的refresh()
我们进入AnnotationConfigApplicationContext的构造方法,this()和register(annotatedClasses)主要初始化spring的基础组件和
注册一个或多个要处理的带注释的类,AOP功能主要在refresh()方法
进入refresh(),里面的逻辑有很多,但Spring-AOP的实现主要看两个方法
registerBeanPostProcessors(beanFactory); // 注册BeanPostProcessor(Bean的后置处理器)
finishBeanFactoryInitialization(beanFactory); // 初始化所有剩下的单实例bean;
因为AnnotationAwareAspectJAutoProxyCreator也是一个BeanPostProcessor,所以AnnotationAwareAspectJAutoProxyCreator的注册就是在registerBeanPostProcessors(beanFactory)方法中实现的,在这一节中,会分很多小节,对registerBeanPostProcessors和finishBeanFactoryInitialization两个方法中的细节进行介绍
1 | public void refresh() throws BeansException, IllegalStateException { |
4.1 registerBeanPostProcessors方法
registerBeanPostProcessors()的主要作用是注册bean的后置处理器来方便拦截bean的创建
下面的源码中,我对一些关键点都做了注释,也会对一些关键方法单独做一个小节来介绍
- 1)、先获取ioc容器已经定义了的需要创建对象的所有BeanPostProcessor
基于章节2的测试,从截图看出,ioc容器有四个BeanPostProcessor
AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等
AnnotationAwareAspectJAutoProxyCreator(处理@EnableAspectJAutoProxy注解,也就是AOP)
2)、给容器中加别的BeanPostProcessor
3)、优先注册实现了PriorityOrdered接口的BeanPostProcessor
4)、再给容器中注册实现了Ordered接口的BeanPostProcessor
5)、注册没实现优先级接口的BeanPostProcessor
6)、把BeanPostProcessor注册到BeanFactory中;
在3、4、5步骤中,注册BeanPostProcessor的时候都会调用beanFactory.getBean(ppName, BeanPostProcessor.class)方法,beanFactory.getBean方法会着重介绍,bean的获取和创建都是基于这个方法
AnnotationAwareAspectJAutoProxyCreator就是在第4步创建的,因为它的父类ProxyProcessorSupport实现了Ordered接口
1 | public static void registerBeanPostProcessors( |
大致脑图如下:
4.2 getBean
AnnotationAwareAspectJAutoProxyCreator是一个BeanPostProcessor
注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
这里以AnnotationAwareAspectJAutoProxyCreator为例:
从beanFactory.getBean()方法获取bean实例的步骤大致如下:
- 1)、创建Bean的实例:AbstractBeanFactory.getBean()->doGetBean()
- 1)、将创建的Bean添加到缓存中singletonObjects(),如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)
- 2)、缓存中获取不到,开始Bean的创建对象流程
- 3)、标记当前bean已经被创建
- 4)、获取Bean的定义信息
- 5)、获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来
- 6)、启动单实例的bean的创建流程
- 7)、创建Bean ,见4.3
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
final String beanName = transformedBeanName(name);
Object bean;
// 1)、将创建的Bean添加到缓存中singletonObjects(),如果没有获取到创建bean
// Eagerly check singleton cache for manually registered singletons.
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
// 2)、缓存中获取不到,开始Bean的创建对象流程
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取父beanFatory 检查这个bean是否创建了
// Check if bean definition exists in this factory.
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// Not found -> check parent.
String nameToLookup = originalBeanName(name);
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
// 3)、标记当前bean已经被创建
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
// 4)、获取Bean的定义信息
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 5)、获取当前Bean依赖的其他Bean;如果有按照getBean()把依赖的Bean先创建出来
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// 6)、启动单实例的bean的创建流程
if (mbd.isSingleton()) {
// //获取到单实例bean后,添加到缓存中 singletonObjects()
sharedInstance = getSingleton(beanName, () -> {
try {
// 7)、创建单实例Bean ,见4.2.1
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
2)、populateBean;给bean的各种属性赋值
3)、initializeBean:初始化bean;
1)、invokeAwareMethods():处理Aware接口的方法回调
- 2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
- 3)、invokeInitMethods();执行自定义的初始化方法
- 4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization();
- 4)、BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功;–>aspectJAdvisorsBuilder
4.2.1 createBean
AbstractAutowireCapableBeanFactory.createBean() 这个类中,有以下几个步骤:
- 1)、解析bean的类型
- 2、让BeanPostProcessor先拦截返回代理对象–>调用resolveBeforeInstantiation方法
- 3)、没有对象,创建一个bean,调用doCreateBean方法
- 4)、返回创建的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
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@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isDebugEnabled()) {
logger.debug("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// 1)、解析bean的类型
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// 2、让BeanPostProcessor先拦截返回代理对象
// 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)、没有对象 创建一个bean
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isDebugEnabled()) {
logger.debug("Finished creating instance of bean '" + beanName + "'");
}
// 4)、返回创建的bean
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
4.2.2 resolveBeforeInstantiation返回代理对象
1 | // 2、让BeanPostProcessor先拦截返回代理对象 |
resolveBeforeInstantiation方法
1 | @Nullable |
applyBeanPostProcessorsBeforeInstantiation方法
1 | @Nullable |
这里源码的注释是“让beanpostprocessor有机会返回代理而不是目标bean实例”,如果成功返回代理对象,则直接返回,否则再执行doCreateBean来创建实例。从开始进入到applyBeanPostProcessorsBeforeInstantiation这个方法中,会但是对于AbstractAutoProxyCreator这个类来说,在执行applyBeanPostProcessorsBeforeInstantiation方法时,它并没有创建,所以并不会执行AbstractAutoProxyCreator的applyBeanPostProcessorsBeforeInstantiation方法和applyBeanPostProcessorsAfterInitialization,返回null,在后面的逻辑中,如果resolveBeforeInstantiation返回null,会执行doCreateBean方法,创建AbstractAutoProxyCreator
4.2.3 doCreateBean创建实例
当resolveBeforeInstantiation返回null时,执行doCreateBean
doCreateBean主要流程是:
- 1)、创建Bean的实例
2)、populateBean;给bean的各种属性赋值
3)、initializeBean:初始化bean;
它的主要步骤在于initializeBean方法上
1 | protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) |
4.3.2 initializeBean初始化bean
- 1)、invokeAwareMethods():处理Aware接口的方法回调
- 2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
3)、invokeInitMethods();执行自定义的初始化方法
4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization()
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
34protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
// 1)、处理Aware接口的方法回调
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 2)、应用后置处理器的postProcessBeforeInitialization()
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
// 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()) {
// 4)、执行后置处理器的postProcessAfterInitialization()
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
5 finishBeanFactoryInitialization
第四章节主要是介绍创建和注册AnnotationAwareAspectJAutoProxyCreator后置处理器的过程
而finishBeanFactoryInitialization(beanFactory)是完成BeanFactory初始化工作、创建剩余的非懒加载单实例bean,也就是我们的业务bean:MathCalculator的创建过程是在这一步完成的
1 | /** |
beanFactory.preInstantiateSingletons()
1 | @Override |
在这个方法里面关注最后一个方法,beanFactory.preInstantiateSingletons()的作用就是创建剩余的非懒加载单实例bean,如下图所示:
我们的业务calculator,LogAspects就是在这里创建的,会调用父类的AbstractBeanFactory的doGetBean方法,执行流程和章节4.2的getBean方法是一个流程
但是创建calculator,LogAspects和创建AnnotationAwareAspectJAutoProxyCreator是有点不同的,在4.2.2章节,我们有提到,创建bean时,resolveBeforeInstantiation(beanName, mbdToUse)方法会尝试返回它的代理对象返回,否则执行doCreateBean创建bean对象,因为AnnotationAwareAspectJAutoProxyCreator已经在第4章节的registerBeanPostProcessors方法中所创建,所以在每一个bean创建之前,都会调用AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation()方法和postProcessAfterInitialization方法
5.1 postProcessBeforeInstantiation()
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessBeforeInstantiation方法如下:
1 | @Override |
这个方法以MathCalculator和LogAspect的创建为例子:
- 1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean),第一次创建肯定是没有的
2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean, 或者是否是切面(@Aspect)
3)、是否需要跳过
1)、获取候选的增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】 每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor; 判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true
2)、永远返回false
5.2 postProcessAfterInitialization()
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialization方法是在
章节4.3.2 initializeBean初始化bean的applyBeanPostProcessorsAfterInitialization调用的
1 | /** |
postProcessAfterInitialization()代码如下:
可以看出,返回了一个wrapIfNecessary(bean, beanName, cacheKey);//如果需要包装
wrapIfNecessary(bean, beanName, cacheKey);代码如下
前面的三个if在5.1已经有过介绍,主要看Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null)
,获取当前bean的所有增强器(通知方法),这里的当前bean也就是MathCalculator,这个方法做了如下几个步骤
1、找到候选的所有的增强器(找哪些通知方法是需要切入当前bean方法的)
2、获取到能在bean使用的增强器。
3、给增强器排序
4、保存当前bean在advisedBeans中;
如果当前bean需要增强,会创建当前bean的代理对象:Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
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);
}
}
// 1)、获取所有增强器(通知方法)
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
2)、保存到proxyFactory
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
3)、创建代理对象:Spring自动决定
return proxyFactory.getProxy(getProxyClassLoader());
}
1)、获取所有增强器(通知方法)
2)、保存到proxyFactory
3)、创建代理对象:Spring自动决定
更多精彩内容:mrxccc