Spring Bean的生命周期和AOP源码流程
2021-05-20 10:00:43 0 举报
Spring Bean的生命周期源码流程
作者其他创作
大纲/内容
缓存中的bean信息为空
advisorNames.length == 0
doGetBean()
不为空
如果实现了xxxAware接口,在这里会调用
注册bean销毁需要的方法
后置处理器的befor方法进来的时候是没有解析过的,所以缓存中没有,before方法就是把切面信息放入缓存中,after方法调用时就会获取到
true,为空
createAopProxy().getProxy(classLoader)
AtAfter
N
获取切面类
N:判断类是不是切面
将bean属性依赖信息存入map中
this.atAspectJAdvisorFactory.getAdvice
Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor)
proxyTargetClass属性设置为true时表示使用cglib动态代理,如果这个属性设置为true时,但是有接,还是使用jdk代理
AtBefore
获取当前类以及父接口
判断容器中是否有InstantiationAwareBeanPostProcessors
(BeanFactoryAdvisorRetrievalHelper)findAdvisorBeans()
调用
sharedInstance != null
构建一个bean定义信息解析器
spring的三级缓存:一级缓存:单例缓存池singletonObjects ;二级缓存:提前早期暴露的单例缓存earlySingletonObjects三级缓存:单例缓存工厂singletonFactoriesspring采用了三级缓存解决了循环依赖的问题
advisorNames = this.cachedAdvisorBeanNames
从代理工厂中获取代理对象
proxyFactory.getProxy(getProxyClassLoader())
AtAfterReturning
对于复杂的bean创建而言就可以使用这种factorybean的getObject()获取bean实例,最常见的例子SqlSessionFactoryBean
advisor instanceof PointcutAdvisor
第一步,找到候选的增强器
处理bean的别名
将bean对应的单例工厂存入单例工厂三级缓存里,从早期暴露的二级缓存里移除beanName
从一级缓存中获取bean信息,第一次是获取不到的
singletonObject = singletonFactory.getObject()
afterSingletonCreation(beanName)
找到方法上的注解
不是
targetClass.isInterface()
给集合里的增强器进行排序
if (matchingBeans.size() > 1)
Y,进行真正的匹配
是,获取增强器
将切面等信息存入缓存中,以便后续做AOP的动态代理,在这里并没有创建代理对象
从factorybean获取bean信息
Y
isPrototypeCurrentlyInCreation(beanName)
这个方法解决了spring属性注入循环依赖的问题
spring是如何解决属性注入的循环依赖的?前期在执行createBeanInstance的方法过程中,会创建早期的对象(属性还没有赋值),并且将早期对象加入到单例工厂三级缓存中,接着会调用populateBean方法给bean的属性进行赋值操作,在这个方法里他会检测bean的依赖关系,比如发现A对象依赖了B对象,就会调用B的getBean方法,B也会执行createBeanInstance方法,将B的早期对象加入三级缓存中,执行populateBean方法时检测到B又依赖了A,接着执行A的getBean方法,这时候调用getSingleton方法时是能够得到A对象的,因为之前已经将A放进了三级缓存,同理,B也能获取到了,至此Spring的属性注入的循环依赖就能得到解决,总共调用了4次getBean方法为什么spring解决不了构造器(@Bean)的循环依赖?因为在执行createBeanInstance这个方法里,会检测是否有构造器的循环依赖,而这时候从缓存里是获取不到bean的,因为在执行完createBeanInstance方法后,才会调用addSingleton方法将bean信息放入缓存,所以构造器循环依赖时是获取不到缓存的,所以不能解决为什么多例也不能解决循环依赖??因为多例模式走的创建bean的过程压根就没有把bean放入缓存中,所以解决不了
BeanFactoryUtils.beanNamesForTypeIncludingAncestors
return new JdkDynamicAopProxy(config)
调用依赖对象的getBean方法
getAdvisorMethods(aspectClass)
如果缓存中bean信息不为空,直接获取工厂bean信息,并返回
不是接口,返回cglib代理
解析依赖
后面的代码太复杂,只知道这里就是创建好bean了
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod)
applyBeanPostProcessorsBeforeInstantiation
2.找到能用的增强器
如果这个bean不是factorybean直接返回,对于期望的factorybean而言,如果不是以以&开头,说明要返回的是FactoryMethod的getObject方法
这个方法会去检测是否有构造器的循环依赖,有的话就直接报错了
byName
如果是工厂方法创建,@Bean
给bean的属性赋值
false
从缓存中获取切面等信息,这时候是能够获取到的,因为之前的resolveBeforeInstantiation方法里已经放入了缓存里
事务源码,事务相关的增强器是在这里找到的
执行factoryBean的回调getObject()方法
调用beanpostprocessor后置处理器的after方法
判断是否需要创建代理对象
value instanceof RuntimeBeanReference,解析引用
sharedInstance = getSingleton(beanName)
是否有必要包装
是接口,返回jdk代理
返回AspectJAfterAdvice
返回AspectJAroundAdvice
aif.getAspectMetadata().getAspectClass()
调用子类AspectJAwareAdvisorAutoProxyCreator
将正在创建的bean从正在创建的map中移除
!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.remove(beanName)
如果一级缓存为空,则判断当前的bean是否正在被创建中,第一次返回false
Object bean = this.beanFactory.getBean(refName)
找到合适的增强器
获取切面类上所有的方法(排除我们@PointCut标注的方法)
clazz.getMethods(),获取class上的所有方法
AtAround
回到外层逻辑
object = factory.getObject()
1.找到增强器集合
判断是否解析过
如果实现了InitializingBean接口,则调用afterPropertiesSet()
findCandidateAdvisors()
prototype多例模式下循环依赖的报错
transformedBeanName(name)
specificInterceptors != DO_NOT_PROXY
eligibleAdvisors.add(candidate)
this.singletonObjects.get(beanName)
循环所有的beanName
当前增强器满足,直接加入到集合中
获取容器中所有组件的名称
beforeSingletonCreation(beanName)
(AspectJAwareAdvisorAutoProxyCreator)shouldSkip
getPointcut
String[] dependsOn = mbd.getDependsOn()
return new ObjenesisCglibAopProxy(config)
postProcessBeforeInstantiation
ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||\t\t\t\tmbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)
AOP寻找切面信息并创建代理对象就是在这个方法里执行的
this.singletonsCurrentlyInCreation.contains(beanName)
多例模式
sortAdvisors(eligibleAdvisors)
getAdvisor
this.beanFactory.getType(beanName)
在这里将正在创建的bean加入map中
if (mbd.isSingleton())
false,使用jdk动态代理
循环匹配方法
返回AspectJAfterThrowingAdvice
mbd.getFactoryMethodName() != null
创建ProxyFactory
0,循环获取到的advisorNames,显示的调用getBean方法获取bean并加入到集合中
返回AspectJAfterReturningAdvice
循环获取的切面方法
初始化bean
如果根据byType找到多个
调用beanpostprocessor后置器处理的before方法
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut)
!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)
优先返回@Primary标记的
hasInstantiationAwareBeanPostProcessors()
实例化切面
返回null
创建代理对象
switch (aspectJAnnotation.getAnnotationType())
ReflectiveAspectJAdvisorFactory
不是切面
如果是单例
从缓存中获取信息
pc.getMethodMatcher()
接着再判断二级缓存中是否为空,并且是否允许引用,allowEarlyReference默认为true
执行真正创建bean的逻辑
真正执行解析的方法
单例模式
isInfrastructureClass(beanClass)
都没有根据名称匹配,如果也没有会报错
@Primary没有,再返回@Priority标记的
this.singletonFactories.get(beanName)
Y:方法上没有上述的注解,表示该方法不是我们要找的切面方法
创建Advisor的实现类
把切面类作为key,找到的增强器集合作为value ,存入缓存中
没找到直接返回空的集合
beforePrototypeCreation(beanName)
如果单例缓存工厂不为空,从三级缓存获取bean信息,并且放入早期暴露的二级缓存中,从单例缓存工厂中移除
aspectJAnnotation == null
先从缓存字段中获取
config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)
将bean放入单例缓存池一级缓存中,从二级和三级缓存中移除bean信息
第一步:从方法上获取切点表达式
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||\t\t\t\tmbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE
singletonObject == null && isSingletonCurrentlyInCreation(beanName)
!isAspect(candidateAspectClass)
寻找依赖的bean
AbstractBeanFactory.getBean(name)
不为空,作为参数传入
!this.inCreationCheckExclusions.contains(beanName) && !this.singletonsCurrentlyInCreation.add(beanName)
判断beanType是否为切面,判断方法是找这个类上是否有@Aspect注解
new ProxyFactory()
代码在执行过程中,如果发现A标记@DependsOn依赖的了B,@DependsOn并不是循环依赖
aspectNames == null
循环beanPostProcessors,如果是InstantiationAwareBeanPostProcessor,执行postProcessBeforeInstantiation
if (singletonObject == null && allowEarlyReference) {
获取方法匹配器
获取bean对应的单例缓存工厂
判断注解的类型
执行解析方法
byType
this.advisorFactory.isAspect(beanType)
this.earlySingletonObjects.get(beanName)
AbstractAdvisorAutoProxyCreator
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&\t\t\t\tisSingletonCurrentlyInCreation(beanName))
判断bean是否为单例的并且是否允许循环引用并且当前bean是否正在创建,如果为true的话,就会将bean对应的早期对象存入单例工厂三级缓存里,从早期暴露的二级缓存里移除beanName三级缓存解决了spring循环依赖的问题,spring的构造器循环依赖是解决不了的
判断我们增强器是否实现了PointcutAdvisor接口
AtAfterThrowing
AtPointcut
通过beanName获取beanType
抛出异常
true
(BeanFactoryAspectJAdvisorsBuilder)buildAspectJAdvisors()
ClassUtils.getAllInterfacesForClassAsSet(targetClass)
afterPrototypeCreation(beanName)
循环调用class
判断对象的注入模型是否为byName或byType
(AbstractAutoProxyCreator)postProcessBeforeInstantiation
InstantiationModelAwarePointcutAdvisorImpl
advisorNames != null
获取bean的增强器
(ReflectiveAspectJAdvisorFactory)getAdvisors(factory)
获取@Value注解的表达式,就是通过这个实现value赋值的
this.advisorRetrievalHelper.findAdvisorBeans()
ajexp == null
处理是否有@DependsOn标记的循环引用
返回AspectJMethodBeforeAdvice
0 条评论
回复 删除
下一页