IOC
2022-03-29 23:44:06 10 举报
初试IOC,仅供参考
作者其他创作
大纲/内容
AutowiredAnnotationBeanPostProcessor
dao存入三级缓存singletonFactories
BeanFactory
service
@ComponentScan
true
bean工厂包含了注入的各种BeanDefinition以及监听等等
invokeAwareMethodsbean可以注入BeanNameAware、BeanFactaryAware、BeanClassLoaderAware
属性注入时解析携带注解的属性
处理@Bean方法
未写完
afterSingletonInstantiated -> 分析所有bean -> 查找携带@EventListener的方法
解析@Import时使用了队列
postProcessBeanFactory初始化事件监听工厂
initializeBean
@Configuration特殊之处
将对象放入监听列表
applyBeanPostProcessorsBeforeInitialization所有实现 BeanPostProcessor 接口的 -> before其中有一个ApplicationContextAwareProcessor增加器调用了InvokeAwareInterfaces,重要的是给bean设置了2个属性。ApplicationEventListenerPublisherApplicatoinContextAware
getBean
EventListenerMethodProcessor
@Autowiredconstruct
解析map到BeanDefinitioin
解析属性populateBean
service完成对象初始化存入一级缓存singletonObjects,删除三级缓存service
dao
refresh()构建Bean对象
将对应信息封装到对象中
ConfigurationClassUtilscheckConfigurationClassCandidate查找配置类
@bean
对象创建完成后解析是否携带注解的方法
BeanDefinitionReaderUtils
ConfigurationClassPostProcessor
doProcessConfigurationClass
三级缓存处理循环依赖
@PostConstruct
add
Set<ApplicationListener<?>>
AbstractAutowireCapableBeanFactory
循环依赖执行流程
registerBeanPostProcessor
注入多个实现了BeanFactoryPostProcessor、 BeanPostProcessor接口的beanDefinition到容器中
@Bean
推断构造创建bean实例
依赖
refresh
如果存在返回值,根据返回的类型也可以进行发布
@Value
CommonAnnotationBeanPostProcessor调用父类InitDestroyAnnotationBeanPostProcessor前置处理器postProcessBeforeInitialization解析带有@PostConstruct注解的方法
ConfigurationClassEnhancerBeanMethodInterceptorintercept
@Autowired
@ImportResource
reflect
ApplicationContextAwareProcessor用于解析实现Aware的6个接口
@Configuration
BeanInstance
根据beanName从容器中获取bean返回
List<BeanPostProcessor>
二级晋级到一级
完整Bean
ApplicationListenerMethodAdaptor(beanName、beanType、监听method)
ConfigurationClassEnhancerenhance
根据beanName从三级缓存获取ObjectFactory,调用其getObject方法时执行getEarlyBeanReference方法,从而得到半成品dao。(当存在AOP时,则会通过AbstractAutoProxyCreator调用其getEarlyBeanReference方法来产生代理对象)将半成品(代理)dao存入二级缓存(earlySingletonObjects)删除三级缓存中dao
isConfigurationCandidate配置候选
finishBeanFactoryInitialization
AbstractBeanFactory
resolveBeanReference
不存在
invokeInitMethods执行实nitializingBeanj接口的afterPropertiesSet
earlySingletonObjects半成品(属性未赋值)
根据method获取beanNameMap<Method,beanName> beanNameCache
获取可以处理event的adaptor
ClassPathBeanDefinitionScanner
ConfigurationClassBeanDefinitionReader
ConfigurationClassBeanDefinitionReaderloadBeanDefinitions
@Component
prepareBeanFactory
ClassLoader
bean
Register
最终将初始化完成的dao存入一级缓存singletonObjects,删除二级缓存dao
ApplicationEventPublisherAware
createBean ---> doCreateBean
@EventListener
CommonAnnotationBeanPostProcessor
singletonFactories暴露生产对象的工厂
解析配置类存入Map
发布
includeFilter
BeanFactoryPostProcessorBeanPostProcessor
AnnotatedBeanDefiniitonReader
@configuration
invokeCustomInitMethod
ApplicationListenerDetector用于解析实现ApplicationListener接口的bean
isCurrentlyInvokedFactoryMethod判断当前调用方法是否是当前解析方法
addSingleton
BeanClass
postProcessBeanFactory子类拓展方法
DefaultSingletonBeanRegister
doGetBean
BeanDefinition
PopulateBean
解析配置类
postProcessBeanDefinitionRegister该方法完成了配置类下包的注解扫描ComponentPropertySourcesComponentScansImportImportResourceBean
applyBeanPostProcessorsAfterInitialization
InitializingBean / afterPropertiesSet
ConfigurationClassPostProcessorpostProcessBeanFactory
@Configuration注解增强配置类
postProcessAfterInitialization
Aware
ApplicationContextAwareProcessor
obtainFreshBeanFactory
ApplicationListenerMethodAdaptor
createBeanInstance
EnvironmentBean
enhanceConfigurationClasses
@Import
getSingleton
AOP代理对象不全是在后置处理产生。因为当AOP标记的对象被其他普通对象依赖注入时,注入的也应该是一个代理对象,但此时还未执行后置处理,不符合实际情况。在属性注入时会根据是否被AOP来判断是否产生一个代理对象,如果产生代理对象,就需要做个记载(earlyProxyReferences),防止在后置处理时重复产生
目的是在处理内部@Bean方法时调用其他@Bean方法的单例问题
DefaultListabelBeanFactory
determineConstructorsFromBeanPostProcessors
onApplicationEvent -> processEvent -> doInvoke
singletonObjects完整对象
service存入三级缓存singletonFactories
postProcessBeforeInitialization
false
ApplicationContextAware
default construct
support
@ComponentScan(basePackages = \"com.example.spring.ioc.anno\")@Configurationpublic class SpringConfig { @Bean public Person person() { return new Person(); } @Bean public MsgEvent msgEvent() { /** * 当使用@Configuration修饰类时 * this是cglib代理bean -> com.example.spring.ioc.anno.SpringConfig$$EnhancerBySpringCGLIB$$58d0644f@b2c5e07 * 调用person()时 -> 是从容器中获取对象 * * 否则 * this普通bean -> com.example.spring.ioc.anno.SpringConfig@5efa40fe * 调用person()时 -> 创建一个新的对象,但是新对象没有被容器管理 */ System.out.println(this); System.out.println(person()); return new MsgEvent(); }}
目标对象处理依赖bean对象从三级缓存中根据依赖beanName获取ObjectFactory,调用getObject方法时执行getEarlyBeanReference方法获取半成品依赖对象,存入二级并删除三级缓存,并通过反射将依赖bean对象赋给目标对象。如果依赖bean对象存在AOP,每次通过三级缓存获取依赖bean时都会调用AbstractAutoProxyCreator类的getEarlyBeanReference方法,每次会产生一个新的代理对象,违反了单例的原则。三级缓存中的二级缓存正好可以保存生成的代理对象,之后再次出现该bean对象的依赖时,直接从二级缓存中获取,有效的避免了多代理的产生
determineCandidateConstructors
@EventListener大致流程
postProcessBeanDefinitionRegistry
三级晋级到二级
no arg construct
prepareRefresh
this()、register()方法注入解析配置类所需要的bean以及配置类对应的bean
invokeBeanFactoryPostProcessor
event
populateBean
BeanPostProcessor
AutowiredAnnotationBeanPostProcessor调用postProcessProperties方法来解析携带@Autowired、@Value的属性
继续处理Dao
初始化前解析携带注解的方法
ApplicationListenerDetecator
createProxyClass
CONFIGURATION_CLASS_ATTRIBUTE== full
beanClass
初始化eventListenerFactories加入 DefaultEventListenerFactory
将半成品dao通过反射注入service
postProcessBeanFactory
processConfigBeanDefinitions
注解
ConfigurationClassParseparse
记录开始时间标志状态修改初始化监听器、监听事件列表
查找配置类
0 条评论
回复 删除
下一页