Spring-AOP源码解析(案例+解析)
@
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模式】
切面类
@Aspect
public class LogAspects {
//抽取公共的切入点表达式
//1、本类引用
//2、其他的切面引用
@Pointcut("execution(public int com.bernard.aop.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.bernard.aop.LogAspects.pointCut()")
public void logEnd(JoinPoint joinPoint){
System.out.println(""+joinPoint.getSignature().getName()+"结束。。。@After");
}
//JoinPoint一定要出现在参数表的第一位
@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+"}");
}
@Around("pointCut()")
public Object logAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("Around: 执行目标方法之前");
Object proceed = proceedingJoinPoint.proceed();
System.out.println("Around: 执行目标方法之后");
return proceed;
}
}
配置类
@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
//业务逻辑类加入容器中
@Bean
public MathCalculator calculator(){
return new MathCalculator();
}
//切面类加入到容器中
@Bean
public LogAspects logAspects(){
return new LogAspects();
}
}
业务逻辑类
public class MathCalculator {
public int div(int i,int j){
System.out.println("MathCalculator...div...");
return i/j;
}
}
测试类
public class IOCTest_AOP {
@Test
public void test01(){
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfigOfAOP.class);
//1、不要自己创建对象
// MathCalculator mathCalculator = new MathCalculator();
// mathCalculator.div(1, 1);
MathCalculator mathCalculator = applicationContext.getBean(MathCalculator.class);
mathCalculator.div(1, 1);
applicationContext.close();
}
}
结果
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两个方法中的细节进行介绍
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//1 刷新前的预处理
prepareRefresh();
//2 获取BeanFactory;刚创建的默认DefaultListableBeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3 BeanFactory的预准备工作(BeanFactory进行一些设置)
prepareBeanFactory(beanFactory);
try {
// 4 BeanFactory准备工作完成后进行的后置处理工作;
// 4.1)、抽象的方法,当前未做处理。子类通过重写这个方法来在BeanFactory创建并预准备完成以后做进一步的设置
postProcessBeanFactory(beanFactory);
/**************************以上是BeanFactory的创建及预准备工作 ****************/
// 5 执行BeanFactoryPostProcessor的方法;
//BeanFactoryPostProcessor:BeanFactory的后置处理器。在BeanFactory标准初始化之后执行的;
//它的重要两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor
invokeBeanFactoryPostProcessors(beanFactory);
//6 注册BeanPostProcessor(Bean的后置处理器)
registerBeanPostProcessors(beanFactory);
// 7 initMessageSource();初始化MessageSource组件(做国际化功能;消息绑定,消息解析);
initMessageSource();
// 8 初始化事件派发器
initApplicationEventMulticaster();
// 9 子类重写这个方法,在容器刷新的时候可以自定义逻辑;
onRefresh();
// 10 给容器中将所有项目里面的ApplicationListener注册进来
registerListeners();
// 11.初始化所有剩下的单实例bean;
finishBeanFactoryInitialization(beanFactory);
// 12.完成BeanFactory的初始化创建工作;IOC容器就创建完成;
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();
}
}
}
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接口
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 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.
// 2.给容器中加其他的BeanPostProcessor
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// 3.优先注册实现了PriorityOrdered接口的BeanPostProcessor;
// 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)) {
// 3.1在beanFactory中获取BeanPostProcessor
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);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// 4.优先注册实现了PriorityOrdered接口的BeanPostProcessor
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// 5.注册没实现优先级接口的BeanPostProcessor
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// 6)、把BeanPostProcessor注册到BeanFactory中;
// 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));
}
大致脑图如下:
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
protected <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
@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返回代理对象
// 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;
}
resolveBeforeInstantiation方法
@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);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
applyBeanPostProcessorsBeforeInstantiation方法
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
这里源码的注释是“让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方法上
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
// 1)、【创建Bean实例】利用工厂方法或者对象的构造器创建出Bean实例;
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType,
beanName);
//判断是否为:MergedBeanDefinitionPostProcessor 类型的,如果是,调用方法
//MergedBeanDefinitionPostProcessor 后置处理器是在bean实例换之后调用的
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
// 判断bean 是否为单实例的,如果是单实例的添加到缓存中
// Eagerly cache singletons to be able to resolve circular references
// even when triggered by lifecycle interfaces like BeanFactoryAware.
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//添加bean到缓存中
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
// 2)、给bean的各种属性赋值
populateBean(beanName, mbd, instanceWrapper);
// 3)、初始化bean
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
if (earlySingletonExposure) {
Object earlySingletonReference = getSingleton(beanName, false);
if (earlySingletonReference != null) {
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
4.3.2 initializeBean初始化bean
- 1)、invokeAwareMethods():处理Aware接口的方法回调
- 2)、applyBeanPostProcessorsBeforeInitialization():应用后置处理器的postProcessBeforeInitialization()
- 3)、invokeInitMethods();执行自定义的初始化方法
- 4)、applyBeanPostProcessorsAfterInitialization();执行后置处理器的postProcessAfterInitialization()
protected 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的创建过程是在这一步完成的
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 类型装换器
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
beanFactory.preInstantiateSingletons()
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
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)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 调用父类AbstractBeanFactory的doGetBean方法
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
在这个方法里面关注最后一个方法,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方法如下:
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
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)
// 3)、是否需要跳过
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;
}
这个方法以MathCalculator和LogAspect的创建为例子:
- 1)、判断当前bean是否在advisedBeans中(保存了所有需要增强bean),第一次创建肯定是没有的
- 2)、判断当前bean是否是基础类型的Advice、Pointcut、Advisor、AopInfrastructureBean, 或者是否是切面(@Aspect)
- 3)、是否需要跳过
- 1)、获取候选的增强器(切面里面的通知方法)【List
candidateAdvisors】
每一个封装的通知方法的增强器是 InstantiationModelAwarePointcutAdvisor;
判断每一个增强器是否是 AspectJPointcutAdvisor 类型的;返回true - 2)、永远返回false
- 1)、获取候选的增强器(切面里面的通知方法)【List
5.2 postProcessAfterInitialization()
AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialization方法是在
章节4.3.2 initializeBean初始化bean的applyBeanPostProcessorsAfterInitialization调用的
/**
* Initialize the given bean instance, applying factory callbacks
* as well as init methods and bean post processors.
* <p>Called from {@link #createBean} for traditionally defined beans,
* and from {@link #initializeBean} for existing bean instances.
* @param beanName the bean name in the factory (for debugging purposes)
* @param bean the new bean instance we may need to initialize
* @param mbd the bean definition that the bean was created with
* (can also be {@code null}, if given an existing bean instance)
* @return the initialized bean instance (potentially wrapped)
* @see BeanNameAware
* @see BeanClassLoaderAware
* @see BeanFactoryAware
* @see #applyBeanPostProcessorsBeforeInitialization
* @see #invokeInitMethods
* @see #applyBeanPostProcessorsAfterInitialization
*/
protected 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 {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
// 注意:这里执行的postProcessBeforeInstantiation并不是5.1章节所执行的bean,他直接返回了传过去的wrappedBean
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
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()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
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自动决定
JdkDynamicAopProxy(config);jdk动态代理;
ObjenesisCglibAopProxy(config);cglib的动态代理;
当postProcessAfterInitialization()执行完后,给容器中返回当前组件使用cglib增强了的代理对象,以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程;
最后我们在执行目标方法前打上断点,查看从容器中获取的MathCalculator对象是什么
通过断点可以看出mathCalculator是一个cglib的代理对象
5.3 获取拦截器链
5.1和5.2执行了前置和后置通知方法后,获取到了mathCalculator的代理对象,接下来就来介绍执行mathCalculator.div(1, 1);
方法,代理对象是如何工作的
通过断点,进入到CglibAopProxy的intercept方法
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
// 1.获取目标对象MathCalculator
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);
// 2.根据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 {
// 4.如果有拦截器链,把需要执行的目标对象,目标方法,拦截器链等信息传入创建一个CglibMethodInvoca// tion 对象,并调用它的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);
}
}
}
5.3.1 getInterceptorsAndDynamicInterceptionAdvice
@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.
// 1.保存所有拦截器
List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
// 2.遍历所有的增强器,将其转为Interceptor
for (Advisor advisor : config.getAdvisors()) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
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;
}
进入到getInterceptorsAndDynamicInterceptionAdvice方法,主要做了一下几个步骤
1.List