Spring IOC、aop、事务加载流程
2021-09-08 17:59:35 0 举报
巨详细,定时更新
作者其他创作
大纲/内容
@ComponentScan
判断手动注册的beanFactoryPostProcessors是否是BeanDefinitionRegistryPostProcessor
return (A) bean
是
// 这个方法同样也是留给子类实现的,springboot也是从这个方法进行启动tomcat的. onRefresh();
//1:准备刷新上下文环境\t\t\tprepareRefresh();
无接口或者ProxyTargetClass =true,CGLIB动态代理。new ObjenesisCglibAopProxy
//保存我们的ImportBeanDefinitionRegistrar对象 currentSourceClass=所在配置类\t\t\t\t\t\tconfigClass.addImportBeanDefinitionRegistrar
后置处理器的【第四次】调用,SmartInstantiationAwareBeanPostProcessor.getEarlyBeanReference
处理BeanFactoryPostProcessor开始
3、refresh()//IOC容器刷新接口
proxyTargetClass==true
//设置bean表达式解析器StandardBeanExpressionResolver
从候选的通知器中找到当前Bean关联的advisorsAopUtils.findAdvisorsThatCanApply
分组调用调用processImport()方法解析
判断重复解析,如果是@Import则覆盖,否则移除重新解析this.configurationClasses.get(configClass)
否
继续判断是否符合条件:// metadata.isIndependent()=顶级类、嵌套类、静态内部类\t\t// metadata.isConcrete() =非接口、非抽象类\t\t// metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName() = 抽象类并且必须方法中有@LookUpisCandidateComponent(sbd)
主要在beanDefinition中增加属性proxyTargetClass=true,这样创建代理对象的时候就会使用cglib方式代理。
真正解析的地方在ConfigurationClassPostProcessor类的this.reader.loadBeanDefinitions(configClasses);
所有BeanDefinitionRegistryPostProcessor调用完毕
ApplicationListenerDetector:主要作用: 1、在Bean初始化完成之后:如果Bean是单例的则并且bean instanceof ApplicationListener。加入到this.applicationListeners中。 2、在Bean销毁之前搞事情: 如果Bean是一个ApplicationListener,则会从ApplicationEventMulticaster(事件广播器)中提前删除了。
重要的集合说明:Set<String> processedBeans:已经执行过的后置处理器的集合List<BeanFactoryPostProcessor> regularPostProcessors:自己设置的普通的bean工厂后置处理器集合List<BeanDefinitionRegistryPostProcessor> registryProcessors:bean定义注册表后置处理器集合List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors:本次要执行的bean定义注册表后置处理器集合List<BeanFactoryPostProcessor> priorityOrderedPostProcessors:保存实现了priorityOrdered的bean工厂后置处理器集合List<String> orderedPostProcessorNames:保存实现了Ordered的bean工厂后置处理器beannames集合List<String> nonOrderedPostProcessorNames:保存普通bean工厂后置处理器beannames集合List<BeanFactoryPostProcessor> orderedPostProcessors:保存实现了Ordered的bean工厂后置处理器集合List<BeanFactoryPostProcessor> nonOrderedPostProcessors:保存普通的的bean工厂后置处理器集合
在容器刷新的时候的invokeBeanFactoryPostProcessors,会解析ImportSelector#selectImports
根据类型获取postProcessorNames:beanFactory.getBeanNamesForType
1、三级缓存为什么要使用工厂而不是直接使用引用?换而言之,为什么需要这个三级缓存,直接通过二级缓存暴露一个引用不行吗? 答:这个工厂的目的在于延迟对实例化阶段生成的对象的代理,只有真正发生循环依赖的时候,才去提前生成代理对象,否则只会创建一个工厂并将其放入到三级缓存中,但是不会去通过这个工厂去真正创建对象;
value=beanFactory.resolveDependency(A)
//从原始的bean定义map中获取bean定义registry.getBeanDefinition(beanName)
如果没有,默认新建DelegatingMessageSource类作为messageSource的Bean
加入一级缓存,删除二、三级缓存。
直接返回纯净对象(未属性赋值对象)
doGetBean(A)
循环postProcessor.postProcessBeanDefinitionRegistry(registry);
5
12、依次链式执行invoke
是否被构造函数解析过if (resolved)
循环我们Import导入进来的所有组件importCandidates
1、AbstractBeanFactory.getObjectForBeanInstance中的getCachedObjectForFactoryBean(beanName)先判断缓存factoryBeanObjectCache是否为空。2、本方法中对一级缓存加锁synchronized (getSingletonMutex())(加锁一级缓存是下面调用factoryBean的getObject创建bean的时候会在一级缓存中新增,这样正在创建bean时候就不会进入)3、再次判断缓存factoryBeanObjectCache是否为空
14
根据scope的get方法来创建(spring支持自定义@Scope)mbd.getScope()
3、处理关于aspectj:初始化LoadTimeWeaverAware Bean实例对象
三种实例化方式,参考文章:https://blog.csdn.net/qq_34886352/article/details/100523473https://blog.csdn.net/qq_22351805/article/details/113547214
AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
一级缓存加锁synchronized (this.singletonObjects)
count = 1 时,设置 MethodOverride 对象的overloaded成员变量为 false。这样做的目的在于,提前标注名称mo.getMethodName()的方法不存在重载,在使用 CGLIB 增强阶段就不需要进行校验,直接找到某个方法进行增强即可。mo.setOverloaded(false)
后置处理器的【第一次】调用 总共有九处调用 事务在这里不会被调用,aop的才会被调用(AbstractAutoProxyCreator类)InstantiationAwareBeanPostProcessor.applyBeanPostProcessorsBeforeInstantiation
13
如果实现了**aware接口,在此调用相关方法
beanFactory.getBean(B)
// 创建事件多播器 initApplicationEventMulticaster();
@Import(TransactionManagementConfigurationSelector.class)
处理@PropertySource注解,@PropertySource注解用来加载properties文件。
// 最后容器刷新 发布刷新事件(Spring cloud也是从这里启动的) finishRefresh();
如果有父容器,也会向父容器里广播一份this.parent.publishEvent(event)
15
注册普通的没有实现任何排序接口的后置处理器
1
循环所有手动注册监听器注册到我们的多播器上1、getApplicationListeners()2、addApplicationListener(listener);
有接口,JDK动态代理。new JdkDynamicAopProxy
主要根据优先级来注册internalAutoProxyCreator,具体顺序为:InfrastructureAdvisorAutoProxyCreator<AspectJAwareAdvisorAutoProxyCreator<AnnotationAwareAspectJAutoProxyCreator。所以如果还有aop的注解,则会覆盖事务的internalAutoProxyCreator
for beanNames
遍历beanNames,触发所有非懒加载单例bean的初始化
doResolveDependency(A)
获取到我们配置类中所有标注了@Bean的方法retrieveBeanMethodMetadata(sourceClass);
三级缓存存在singletonFactory != null
判断@Condition是否满足条件
判断BeanFactory是否已经存在生命周期处理器,如果不存在,则使用DefaultLifecycleProcessor
2、register(annotatedClasses)//注册我们的配置类
获取所有Lifecycle类getLifecycleBeans()
将实例存放在三级缓存中,解决循环依赖addSingletonFactory
// 调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition 2.bean工厂的后置处理器调用 invokeBeanFactoryPostProcessors(beanFactory);
只有Spring 和SpringMvc整合的时才会有父子容器的概念getParentBeanFactory()
@Bean
使用父定义pbd构建一个新的RootBeanDefinition对象(深拷贝)。mbd = new RootBeanDefinition(pbd);用子 BeanDefinition 中的属性覆盖父 BeanDefinition 中的属性。mbd.overrideFrom(bd);
判断ListableBeanFactory是否为BeanDefinitionRegistry
6,调用proceed
后置处理器的【第五次】调用,在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改bean 状态的机会.InstantiationAwareBeanPostProcessor. postProcessAfterInstantiation
bd.getParentName() == null
AutoProxyRegistrar#registerBeanDefinitions
5、实例化所有剩余(非懒加载)单例对象preInstantiateSingletons
用的是aop接口方式
new AnnotationConfigApplicationContext(Config.class)
Spring支持component索引技术,需要引入一个组件,大部分项目没有引入这个组件,所以会进入scanCandidateComponents方法ClassPathScanningCandidateComponentProvider.scanCandidateComponents
把@Import的ConfigurationClass注册为bean定义
说明存在父BeanFactory,获取父定义的MergedBeanDefinition
将父类的BeanDefinition与子类的BeanDefinition进行合并覆盖getMergedLocalBeanDefinition(beanName)
//循环处理我们包扫描出来的bean定义scannedBeanDefinitions
是否实现DeferredImportSelector接口
refresh()
AspectJAfterThrowingAdvice
invoke(this)
//判断是否需要跳过,其实是判断@Conditional是否匹配shouldSkip
getBean(B)
//new一个ConfigurationClass,用importedBy来设置是从哪个类import进来的candidate.asConfigClass(configClass)
循环configCandidates
调用前置通知this.advice.before
value=beanFactory.resolveDependency(B)
按照group 或者 deferredImport 进行分组groupings.computeIfAbsent
尝试去一级缓存获取beanthis.singletonObjects.get(beanName)
//属性编辑器支持ResourceEditorRegistrar
第一步
应用监听器探测器的后置处理器ApplicationListenerDetector
2、如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
重写了MethodMatcher的matches方法,如果为空或者标注了@Transaction(tas.getTransactionAttribute),则匹配成功。
第三步
判断bean定义是否解析过
inject(B)
调用实现了BeanFactoryPostProcessor和Ordered接口的invokeBeanFactoryPostProcessors方法
用于导入Spring的配置文件,与@Import的ImportBeanDefinitionRegistrar相似,先加入集合configClass.addImportedResource
添加早期事件earlyApplicationEvents,或者委托给多播器发布事件:multicastEvent
//用来扫描classpath下面的标注了@service、@Component、@Respository、@Controller注解new ClassPathBeanDefinitionScanner
调用自定义重写的selector的selectImports
否(则创建bean)
第一次访问返回null;第二次返回未属性赋值的早期对象。
系统内部的后置处理器,即MergedBeanDefinitionPostProcessor类型的后置处理器
不为空
循环代码
设置了重要的类TransactionAttributeSourcePointcut:它决定了哪些类会被切入,从而生成的代理对象
设置了一些忽略自动装配的接口
4、aop加载流程
//判断当前构造函数是否被解析过\t\tboolean resolved = false;\t\t//有没有必要进行依赖注入\t\tboolean autowireNecessary = false;
循环我们自定义的配置类candidates
wrapIfNecessary
添加一个后置处理器:ApplicationContextAwareProcessor,此后置处理处理器实现了BeanPostProcessor接口,在Bean的初始化前、后调用,调用各种Aware方法
MethodBeforeAdviceInterceptor
对我们的advisor进行排序sortAdvisors
3
1、为我们的bean工厂创建类型转化器CONVERSION_SERVICE_BEAN_NAME
判断是否候选组件,通过excludeFilters和includeFilters。isCandidateComponent(metadataReader)
@bean--BeanMethods
注册通过@bean注解标注的类
直接返回return mbd.getBeanClass()
//把@Bean的方法存储起来,并未解析configClass.addBeanMethod
说明没有bean定义的能力,直接执行beanFactoryPostProcessors的postProcessBeanFactory方法
存到bean定义集合registryProcessors,后续统一执行父类BeanFactoryProcessor接口中的方法。
否,继续循环
注入了两类:1、AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar2、ProxyTransactionManagementConfiguration是一个@Configuration
获取事件类型:ApplicationEvent或者PayloadApplicationEvent
//找到候选的ComponentsfindCandidateComponents
遍历所有注解,获取注解上的所有属性。AnnotationConfigUtils.attributesFor()
调用实现了BeanFactoryPostProcessor接口的invokeBeanFactoryPostProcessors方法
11,调用proceed
匹配流程总结:
解析mode和proxyTargetClass这两个属性
// 内部有两个标记位来标记是否已经处理过了,这里会引发一连串知识盲点,当我们注册配置类的时候,可以不加Configuration注解,直接使用Component ComponentScan Import ImportResource注解,称之为Lite配置类,如果加了Configuration注解,就称之为Full配置类// 如果我们注册了Lite配置类,我们getBean这个配置类,会发现它就是原本的那个配置类 // 如果我们注册了Full配置类,我们getBean这个配置类,会发现它已经不是原本那个配置类了,而是已经被cgilb代理的类了 // 写一个A类,其中有一个构造方法,打印出“你好” // 再写一个配置类,里面有两个bean注解的方法 // 其中一个方法new了A 类,并且返回A的对象,把此方法称之为getA // 第二个方法又调用了getA方法 // 如果配置类是Lite配置类,会发现打印了两次“你好”,也就是说A类被new了两次 // 如果配置类是Full配置类,会发现只打印了一次“你好”,也就是说A类只被new了一次,因为这个类被cgilb代理了,方法已经被改写
循环所有配置类loadBeanDefinitionsForConfigurationClass
循环解析sourceClass
为空
设置何种方式代理applyScopedProxyMode
把之前的beanMethod注册为bean定义--ConfigurationClassBeanDefinition
A、B循环依赖
如果LifecycleGroup不为空,则获取每个阶段下所有的lifecycleBean,然后调用其start方法phases.get(key).start()
//真正的解析我们的配置类\t\t\tparser.parse(candidates);
对象工厂(singletonFactories)存储在三级缓存中。
后置处理器的【第三次】调用,MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition
其实是调用lambda表达式的 createBean() 方法singletonFactory.getObject()
pointcutExpression.couldMatchJoinPointsInType(targetClass)
尝试从单例缓存池中获取对象this.singletonObjects.get(beanName)
count = 0,表明根据方法名未找到相应的方法,此时抛出异常
循环postProcessorNames获取实现PriorityOrdered->Ordered->剩余的BeanDefinitionRegistryPostProcessor
调用初始化方法,InitializingBean的afterPropertiesSet、initMethod invokeInitMethods
DependencyDescriptor.resolveCandidate(A)
getBean(beanName)
判断这个FactoryBean是否希望急切的初始化
初始化bean对象:initializeBean(A)
beanFactory.getBean(A)
有参构造函数或者是工厂方法是否解析过if (autowireNecessary)
9
3、aop链式调用过程
1、通过bean的后置处理器来进行后置处理生成代理对象(实现了InstantiationAwareBeanPostProcessor接口,并且在postProcessBeforeInstantiation中返回了Object,那么Spring将不会执行doCreateBean进行实例化,而是将当前用户返回的bean实例直接返回);2、在这一步是我们aop和事务的关键,因为在这里解析我们的aop切面信息进行缓存。resolveBeforeInstantiation
用到了双重检查加锁DCL
调用的地方:finishBeanFactoryInitialization(beanFactory)中的 beanFactory.preInstantiateSingletons();因为EventListenerMethodProcessor 实现了接口 SmartInitializingSingleton,在初始化所有bean后,调用smartSingleton.afterSingletonsInstantiated()
SmartLifecycle中的getPhase方法,实现了Lifecycle的直接返回0int phase = getPhase(bean)
else if
2、工厂方法,xml中使用factory-method,注解配置类中使用@Bean。instantiateUsingFactoryMethod
AspectJAfterAdvice
ImportBeanDefinitionRegistrar
getSingleton(A)
//再次当做配置类递归解析,如果不是配置类,最终当作普通bean定义注册ConfigurationClassParser.processConfigurationClass(candidate.asConfigClass(configClass));
递归调用getBean,获取depentceOn的bean。getBean(dep)
按照PriorityOrdered、Ordered等进行优先级排序deferredImports.sort
循环registerBean(annotatedClass);
检查具有指定名称的方法是否存在,如果没有找到,则将其标记为未重载。 prepareMethodOverride(mo)
@Autowired注入为例
//把我们扫描出来的类变为bean定义的集合 真正的解析ComponentScanAnnotationParser.parse
//设置类加载器
调用beanFactory.getBean获取BeanPostProcessor
调用getObjectForBeanInstance
获取所有注解,并非只有事务注解,因为@EnableAspectJAutoProxy等注解也有mode、proxyTargetClass等属性。getAnnotationTypes()
尝试解析bean定义doResolveBeanClass
advisor instanceof PointcutAdvisor#canApply
循环手动设置的beanFactoryPostProcessors
遍历beanNames,触发所有SmartInitializingSingleton的后初始化回调
是否含有class实例mbd.hasBeanClass()
设置了一些允许自动装配的接口,并且进行了赋值操作
触发SmartInitializingSingleton实现类的afterSingletonsInstantiated方法。这也是事件监听器,注解@EventListener方式被调用的地方
设置实现TransactionManagementConfigurer接口的TransactionManager:setConfigurers
该配置类,通过@Bean的方式注入了一个internalTransactionAdvisor类型的BeanFactoryTransactionAttributeSourceAdvisor
16
//1、注册一些内置的后置处理器//2、注册相关的BeanDefinition AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
createBean(A)
2、//设置@AutoWired的候选的解析器,该解析器可以处理@Lazy注解,不会立即创建注入属性的实例,而是生成代理对象 beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
doResolveDependency(B)
else
注册一个监听器工厂,用以支持@TransactionalEventListener注解标注的方法。
doCreateBean(B)
后置处理器的【第八次】调用,BeanPostProcessor.postProcessAfterInitialization
// 注册我们bean的后置处理器\t\t\t\tregisterBeanPostProcessors(beanFactory);
继续执行getSingleton的addSingleton(A)
// 实例化我们剩余的单实例bean.\t\t\t\tfinishBeanFactoryInitialization(beanFactory);
invokeJoinpoint()
把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除
Spring Boot的自动配置中有DeferredImportSelectors接口的大量实现
和aop的matches走的是两个不同而matches
configCandidates是否为空
ApplicationListenerDetector后置处理器的postProcessAfterInitialization方法会再次addApplicationListener为了防止漏网之鱼,如懒加载的bean
@EnableAspectJAutoProxy
Y
//设置@CompentScan导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义//设置@Import导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义生成器为:internalConfigurationBeanNameGenerator
判断当地的bean是否正在创建
配置类进行排序
// 第四:留个子类去实现该接口 postProcessBeanFactory(beanFactory);
通过多播器发布早期事件etApplicationEventMulticaster().multicastEvent(earlyEvent)
if (alreadyThere != null)
遍历所有实现了SmartLifecycle接口,仅仅实现Lifecycle接口的类手动启动容器才会调用(autoStartupOnly为false)
进行后置处理 @AutoWired @Value的注解的预解析 applyMergedBeanDefinitionPostProcessors
doGetBean(B)
调用父类构造器:GenericApplicationContext()
ImportBeanDefinition注解导入
执行currentRegistryProcessors中的ConfigurationClassPostProcessor中的postProcessBeanDefinitionRegistry方法
spring的事件监听有三个部分组成:1、事件(ApplicationEvent) 负责对应相应监听器2、监听器(ApplicationListener) 对应于观察者模式中的观察者。3、事件发布器(ApplicationEventMulticaster )对应于观察者模式中的被观察者/主题, 负责通知观察者4、EventMultiCaster:事件发布器会把消息发送到EventMultiCaster,再由它来发布事件给监听器
判断是否正在创建(创建中的Bean的名字会被保存在singletonsCurrentlyInCreation中,见beforeSingletonCreation(beanName);)isSingletonCurrentlyInCreation(beanName)
DependencyDescriptor.resolveCandidate(B)
判断我们的通知能不能作用到当前的类上findAdvisorsThatCanApply
处理配置类接口 默认方法的@BeanprocessInterfaces
后置处理器的【第二次】调用,进行选举出合适的构造函数对象SmartInstantiationAwareBeanPostProcessor.determineConstructorsFromBeanPostProcessors
4、Transactional加载过程
父类AbstractTransactionManagementConfiguration
1、class类型:return (Class<?>) evaluated2、String类型:ClassUtils.forName:(通过c类加载器加载:clToUse.loadClass(name) ,或者反射: Class.forName(name))
后置处理器的【第八次】调用,代理对象已经生成。BeanPostProcessor.applyBeanPostProcessorsAfterInitialization
proxyFactory.getProxy
groupings是否为空
在ComponentScanAnnotationParser的pase时候,会new ClassPathBeanDefinitionScanner,此时构造函数的registerDefaultFilters()方法会设置includeFilters,其中就包换Component.class
还有一种spring2.0的xml配置方式
根据beanName和对应的BeanDefinition,获取MergedBeanDefinition。getMergedBeanDefinition
普通类(当做配置类再解析)
mbd.resolveBeanClass
调用ObjectFactory的getObject方法,即addSingletonFactory的getEarlyBeanReference回调方法,一般情况直接返回bean对象(真正实现了getEarlyBeanReference方法的后置处理器只有一个,就是通过@EnableAspectJAutoProxy注解导入的AnnotationAwareAspectJAutoProxyCreator,会返回一个代理对象)
针对prototype的循环依赖,spring无法解决,此处会抛出异常isPrototypeCurrentlyInCreation(beanName)
finishBeanFactoryInitialization(beanFactory)
是否为多例beanmbd.isPrototype()
根据当前bean找到匹配的advisorgetAdvicesAndAdvisorsForBean
1、IOC加载
//创建一个容器用于保存早期待发布的事件集合早期事件不需要手动publishEvent发布, 在registerListeners中会自动发布, 发布完早期事件就不存在了。this.earlyApplicationEvents = new LinkedHashSet<>();
强制使用cglib动态代理。AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry)
自己写了个类,实现了BeanDefinitionRegistryPostProcessor接口,也打上了@Component注解,但是这里没有获得,因为直到这一步,Spring还没有完成扫描,扫描是在ConfigurationClassPostProcessor类中完成的,也就是下面第一个invokeBeanDefinitionRegistryPostProcessors方法。
获取@EnableTransactionManagement的属性值,并保存到AnnotationAttributes enableTx中
循环basePackages
循环candidates
1、添加到当前处理集合currentRegistryProcessors2、添加到执行过的后置处理器的集合processedBeans(后续根据这个集合太避免重复执行)
添加到集合configurationClasses
创建动态代理createProxy
//添加一个后置处理器:ApplicationListenerDetector,此后置处理器实现了BeanPostProcessor接口
尝试去二级缓存中获取对象(二级缓存中的对象是一个早期对象,)即未被属性赋值的纯净)对象)earlySingletonObjects.get(beanName)
设置了一个属性源:AnnotationTransactionAttributeSource。设置了一个通知advice(其实是个拦截器):TransactionInterceptor。
调用doStart方法
拿到beanName对应的bean实例getSingleton(beanName)
获取所有bean定义的名称(容器this()调用时注册的)registry.getBeanDefinitionNames()
注册实现了Order的后置处理器
是有有异常
标记bean正在创建,在这里会把beanName加入进来,第二次循环依赖若是构造器注入会抛出异常beforeSingletonCreation(beanName)
createAopProxy
populateBean(A)
aop功能中在这里传入的是Object.class,代表去容器中获取到所有的组件的名称,然后再经过一一的进行遍历,这个过程是十分的消耗性能的,所以说spring会再这里加入了保存切面信息的缓存。但是事务功能不一样,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。所以spring在事务模块中没有加入缓存来保存我们的事务相关的advisor
处理配置类的父类的 ,循环再解析
AfterReturningAdviceInterceptor
结束
BeanFactory接口的时候 发DefaultListableBeanFactory是最底层的实现,功能是最全的,所以创建该对象
从三级缓存中删除掉\t\t\t\t\t\tthis.singletonFactories.remove(beanName);
//尝试去缓存中获取对象(这段代码和解决循环依赖有关)getSingleton(beanName)
17
1、执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry2、添加到registryProcessors(用于最后执行postProcessBeanFactory方法)
//加入到集合中\t\t\t\t\t\t\t\tcandidates.add(sbd);
调用实现了BeanFactoryPostProcessor和PriorityOrdered接口的invokeBeanFactoryPostProcessors方法
根据类型获取容器中所有单利的非懒加载的ApplicationListener,注册到我们的多播器上1、getBeanNamesForType2、addApplicationListenerBean(listenerBeanName)(注册的是beanName,非实例对象,在SimpleApplicationEventMulticaster的multicastEvent方法中会getApplicationListeners,来根据beanName来getBean)
循环candidateNames
AutoProxyRegistrar
调用构造函数
把singletonsCurrentlyInCreation标记正在创建的bean从集合中移除\t\t\t\t\tafterSingletonCreation(beanName);
后置处理器的【第六次】调用,对属性的值进行相应的处理(修改PropertyValues)InstantiationAwareBeanPostProcessor.postProcessPropertyValues
Spring使用了font color=\"#ff0000\
调用factoryBean的后置处理器postProcessObjectFromFactoryBean
解析注解
如果设置proxy-target-class=\"true\",则使用CGLIB的代理。
//递归处理内部类,一般不会写内部类processMemberClasses
// 初始化国际化资源处理器.\t\t\t\tinitMessageSource();
//处理我们延时的DeferredImportSelectors,延迟Import会在@Configuration之后解析,我们springboot就是通过这步进行记载spring.factories文件中的自定装配的对象 processDeferredImportSelectors();
// 此处才把@Bean的方法和@Import 注册到BeanDefinitionMap中\t\t\tthis.reader.loadBeanDefinitions(configClasses);
return (B) bean
发布容器启动完毕事件\t\tpublishEvent(new ContextRefreshedEvent(this))
获取父定义的MergedBeanDefinition递归getMergedBeanDefinition(parentBeanName)
清空currentRegistryProcessors
加到集合deferredImportSelectors
BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
继续执行getSingleton的afterSingletonCreation(B)
AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(A)
继续执行getSingleton的addSingleton(B)
与@EnableAspectJAutoProxy不同,此处@Import的是ImportSelector,而非ImportBeanDefinitionRegistrar。
循环我们的bean定义(BeanPostProcessor)for (String ppName : postProcessorNames)
调用:this.reader = new AnnotatedBeanDefinitionReader(this);//创建一个读取注解的Bean定义(BeanDefinition)读取器
1、this()//调用构造函数
@ImportResource
4,调用proceed
是否为单例beanmbd.isSingleton()
BeanNameAware :可以获取容器中bean的名称BeanFactoryAware:获取当前beanfactory这也可以调用容器的服务BeanClassLoaderAware:获取类加载器实现这些类的接口会在其他地方加载。
早期bean覆盖现在的
AopConfigUtils.registerAutoProxyCreatorIfNecessary
二级缓存没有且允许循环引用if (singletonObject == null && allowEarlyReference)
font color=\"#ff0000\
//真正解析方法doProcessConfigurationClass
创建一个配置类解析器对象ConfigurationClassParser
10
加入缓存beforeSingletonCreation(beanName);
ExposeInvocationInterceptor
如果是创建对象,不是仅仅类型检查markBeanAsCreated(beanName)
处理lookup-method 和 replace-method(仅在XML方式中),这两个配置存放在 BeanDefinition 中的 methodOverridesmbdToUse.prepareMethodOverrides()
(粗筛)进行类级别过滤matches(targetClass)
后置通知:invokeAdviceMethod
createBean(B)
解析ImportBeanDefinitionRegistrar类型,执行其registerBeanDefinitions方法
doCreateBean(A)
不会操作缓存,直接创建beancreateBean
封装成SourceClassasSourceClass(configClass)
//忽略给定接口的自动装配功能\t\tignoreDependencyInterface(BeanNameAware.class);\t\tignoreDependencyInterface(BeanFactoryAware.class);\t\tignoreDependencyInterface(BeanClassLoaderAware.class);
ConfigurationClassBeanDefinitionReader.loadBeanDefinitions@Import和@Bean的bean定义在此处解析
//如果没有注册过bean名称为XXX,spring就自己创建一个名称为XXX的singleton bean
AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(B)
inject(A)
AbstractAutoProxyCreator#postProcessAfterInitialization
Spring使用了DCL双重检测锁机制来记录对象正在创建//没有创建\t\tif (!this.alreadyCreated.contains(beanName)) {\t\t\t//全局加锁\t\t\tsynchronized (this.mergedBeanDefinitions) {\t\t\t\t//再次检查一次:DCL 双检查模式\t\t\t\tif (!this.alreadyCreated.contains(beanName)) {
判断我们的bean的属性注入模型.根据bean的属性名称注入:autowireByName根据bean的类型进行注入:autowireByType
判断容器中是否有messageSource的bean对象beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)
调用:this.scanner = new ClassPathBeanDefinitionScanner(this);
检测类的访问权限。默认情况下,对于非 public 的类,是允许访问的。
返回通知:this.advice.afterReturning
2、循环依赖
打印日志
spring1.2基于接口的配置方式findCandidateAdvisors
mode == AdviceMode.PROXY
存在父定义,需要与父定义合并
递归解析直到成普通组件
表明无父配置,这时直接将当前的 BeanDefinition 升级为 RootBeanDefinition
说明是普通的beanFactoryPostProcessor,添加到regularPostProcessors(用于最后执行postProcessBeanFactory方法)
真正扫描ClassPathBeanDefinitionScanner.doScan
真正的创建我们的bean的实例对象的过程,给bean的属性赋值,调用bean的初始化操作以及 生成代理对象 都是在这里doCreateBean
getBeanFactoryPostProcessors解释:spring允许我们手动添加BeanFactoryPostProcessor即:AnnotationConfigApplicationContext annotationConfigApplicationContext =new AnnotationConfigApplicationContext(AppConfig.class); annotationConfigApplicationContext.addBeanFactoryPostProcessor(XXX);
解析@ComponentScan属性scopedProxy、includeFilters、excludeFilters、lazyInit等
@propertySource
1、获取IOC容器的bean定义是否大于原始加载的bean定义candidateNames2、如果大于,则再判断表示当前循环的还有没有没被解析过(ConfigurationClassUtils.checkConfigurationClassCandidate:会设置标记,是正式配置类full,非正式配置类lite),如果没有则添加到candidates
循环结束
第二步
直接从三级缓存中获取 ObjectFactory对象(font color=\"#ff0000\
@DependsOn为空
循环解析componentScans
//扫描指定包路径下面的所有.class文件\t\t\tResource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
start
是否通过@Import导入configClass.isImported()
@EnableTransactionManagement
1、调用spring内置的internal*开头的实现了BeanFactoryPostProcessor的invokeBeanDefinitionRegistryPostProcessors2、调用自定义实现了BeanFactoryPostProcessor和Order接口的invokeBeanDefinitionRegistryPostProcessors3、调用自定义实现了BeanFactoryPostProcessor的invokeBeanDefinitionRegistryPostProcessors4、调用自定义实现了BeanFactoryPostProcessor的invokeBeanFactoryPostProcessors其中第4步,会调用ConfigurationClassPostProcessor的postProcessBeanFactory来创建cglib动态代理enhanceConfigurationClasses方法只有full版配置类才会创建cglib代理\t\t\t 虽然我们在指定配置的时候不标注@Configuration也行,所以加不加注解的区别就在这里\t\t\t 那么加了@Configuration和不加有本质上有什么区别的?\t\t\t 当在配置类中一个@Bean 使用方法的方式引用另一个Bean如果不加注解就会重复加载Bean\t\t\t 如果加了@Configuration 则会在这里创建cglib代理,当调用@Bean方法时会先检测容器中是否存在
排序sortPostProcessors
解析@Lazy@DependsOn等注解processCommonDefinitionAnnotations
获取bean定义,判断是否是fectoryBean
@ImportResources导入
4、注册处理@Autowired 注解的处理器、注册处理@Required属性的注解处理器、注册处理JSR规范的注解处理器、注册处理jpa注解的处理器、注册处理监听方法的注解@EventListener解析器、注册事件监听器工厂
//加入扫描@Component的、JSR250规范的、JSR330规范的。(这也是为啥我们标注了@Compent @Repository @Service @Controller 能够被识别解析)registerDefaultFilters();
startBeans(true)
//2:获取告诉子类初始化Bean工厂 不同工厂不同实现\t\t\tConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//创建一个早期事件监听器对象this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
继承自StaticMethodMatcherPointcut,所以`ClassFilter classFilter = ClassFilter.TRUE;`: 匹配所有的类。但自己重写了ClassFilter的matches方法,即TransactionalProxy、TransactionManager、PersistenceExceptionTranslator即这三个类不会被代理。
解析代码
调用AbstractAutowireCapableBeanFactory()
注册实现了priorityOrdered的后置处理器
是否满足代理条件
ImportSelector
容器中有没有InstantiationAwareBeanPostProcessors的后置处理器
//解析bean定义判断是不是完全的配置类 还是一个非正式的配置类,并设置full配置类或者lite配置类checkConfigurationClassCandidate
invokeAdviceMethod
初始化bean对象:initializeBean(B)
//获取@Import注解的类getImports(sourceClass)
N
清除上下文级别的资源缓存clearResourceCaches()
先启动以来的bean,再启动自身bean.start()
AbstractFallbackTransactionAttributeSource#getTransactionAttribute
//返回DefaultListableBeanFactory类(实现了ConfigurableListableBeanFactory)getBeanFactory()
继续执行getSingleton的afterSingletonCreation(A)
@Import
获取解析过的AdvisorfindCandidateAdvisors()
2、注解@EventListener方式
getBean(A)
1、实现接口方式
populateBean(B)
1、如果methodMatcher == MethodMatcher.TRUE,则匹配所有方法。2、进行类或者接口方式匹配。3、进行方法匹配: 1)、按照切点方式匹配( AspectJ方式) 2)、按照aop接口方式(Advisor匹配器)--事务用该方式匹配案例:git@gitee.com:chaolovechun/studyNotes.git的com.wyc.aop.advisormatch模块。
for Advisors
ProxyTransactionManagementConfiguration
1、//注册了实现Order接口的排序器 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
AnnotationTransactionAttributeSource:它是基于注解驱动的事务管理的事务属性源,和@Transaction相关,也是现在使用得最最多的方式。TransactionAttributeSource子类有:AnnotationTransactionAttributeSource、NameMatchTransactionAttributeSource、MethodMapTransactionAttributeSource等。
//3:对bean工厂进行填充属性\t\t\tprepareBeanFactory(beanFactory);
判断容器中是没有有我们自定义的applicationEventMulticaster 应用多播器组件
判断父类beanname是否相同!beanName.equals(parentBeanName)
为ApplicationContext spring上下文对象初始beanFactory
获取BeanDefinition的classNamembd.getBeanClassName()
candidates是否为空
if (className != null)
第四步
返回结果
7
//把我们的事件监听器注册到多播器上\t\t\t\tregisterListeners();
2,调用proceed
获取方法名为 mo.getMethodName() 的方法数量,当方法重载时,count 的值就会大于1ClassUtils.getMethodCountForName
根据className解析成表达式evaluateBeanDefinitionString
candidateNames是否为空
@AspectJ注解驱动方式buildAspectJAdvisors
getImportGroup():子类可以对一些Import的类进行分类,若不复写,默认return null
再次缓存中获取,可能存在调用getObject的时候,另一个线程已经创建好bean,避免重复创建this.factoryBeanObjectCache.get(beanName)
注册lifecycleProcessor 声明周期处理器作用:当ApplicationContext启动或停止时,它会通过LifecycleProcessor来与所有声明的bean的周期做状态更新initLifecycleProcessor()
4、冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
后置处理器的【第七次】调用,解析@PostConstruct等BeanPostProcessor.postProcessBeforeInitialization
AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
注册当前spring容器到LiveBeansView,提供servlet(LiveBeansViewServlet)在线查看所有的bean json 、 为了支持Spring Tool Suite的智能提示\t\tLiveBeansView.registerApplicationContext(this)
@Import--ImportedBy
如果当前容器正在当前Bean进行销毁,则直接抛出异常
为实现了SmartLifecycle并且isAutoStartup 自动启动的Lifecycle调用start()方法 getLifecycleProcessor().onRefresh()
移除缓存afterSingletonCreation(beanName)
preInstantiateSingletons()
getSingleton(B)
遍历DeferredImportSelector接口集合
没有则用默认的SimpleApplicationEventMulticaster
//解析bean定义ConfigurationClassPostProcessor.processConfigBeanDefinitions
8,调用proceed
收藏
0 条评论
回复 删除
下一页