spring自动装配的原理
启动类的@SpringBootApplication注解由@SpringBootConfiguration,@EnableAutoConfiguration,@ComponentScan三个注解组成,三个注解共同完成自动装配;
@SpringBootConfiguration 注解标记启动类为配置类
@ComponentScan 注解实现启动时扫描启动类所在的包以及子包下所有标记为bean的类由IOC容器注册为bean
@EnableAutoConfiguration通过 @Import 注解导入 AutoConfigurationImportSelector类,然后通过AutoConfigurationImportSelector 类的 selectImports 方法去读取需要被自动装配的组件依赖下的spring.factories文件配置的组件的类全名,并按照一定的规则过滤掉不符合要求的组件的类全名,将剩余读取到的各个组件的类全名集合返回给IOC容器并将这些组件注册为bean
Bean的生命周期(重点)
(BeanDefinition包含了bean标签的相关信息bean的类名、bean的作用域、初始化方法、销毁方法、依赖关系等信息)
填充BeanDefinitionMap的进入方法obtainFreshBeanFactory()
实例化bean的方法->finishBeanFactoryInitialization
xml方式:
BeanDefinition阶段:
1.读取配置文件封装BeanDefinition
(源码:在XmlBeanDefinitionReader类中的doLoadBeanDefinitions方法中的registerBeanDefinitions(doc, resource))进入该方法后还有个documentReader.registerBeanDefinitions(doc, this.createReaderContext(resource));
后面还有一直到BeanDefinitionReader 接口的实现类
DefaultBeanDefinitionDocumentReader的 parseBeanDefinitions方法用来解析标签
2.将BeanDefinition存储到BeanDefinitionMap中
3.执行Bean工厂后处理器(beanFactorypostProcessor和BeanDefinitionRegistryPostProcessor)
Bean的实例化阶段:循环遍历BeanDefinitionMap中的BeanDefinition通过反射原理进行创建bean对象。
Bean的初始化阶段:进行实例的属性填充populate,执行Aware接口方法,执行BeanPostProcessor接口的postprocessorbeforeInitialization方法,执行InitializingBean接口的afterPropertiesSet初始化方法,执行自定义初始化Init方法,执行BeanPostProcessor的after方法。
Bean的存储阶段:将实例化并初始化好的Bean存储到单例池singletonObjects中
spring整合mybatis注解方式的原理**(springboot会自动整合sqlSessionFactory整合ClassPathMapperScanner会少步骤)
spring主要通过MapperScan注解整合mybatis
(后续会添加图片)
解析MapperScan的时候会解析这个import注解,向spring容器注入MapperScannerRegistrar,然后执行这个类实现的ImportBeanDefinitionRegistrar接口的方法(重写后方法),来spring容器注册MapperScannerConfigurer的BeanDefinition(BD),并传入mapper的路径(basePackage)。
然后因为MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor这个接口,spring容器会从BDMap中拿到MapperScannerConfigurer这个BD,去执行PostProcessorBeanDefinitionRegistry方法,在这个方法里面会new 一个ClassPathMapperScanner(继承自ClassPathBeanDefinitionScanner),执行scan方法(在父类中),会先执行子类的doscan然后执行父类的doscan,父类doscan的主要作用是加载(指定的)basePackage下的mapper.class文件,创建BD放入到BDmap中,然后在子类的doscan中继续执行processBeanDefinitions方法,这个方法的内部最重要的步骤是设置BD的beanClass为MapperFactoryBean(源码:definition.setBeanClass(this.mapperFactoryBeanClass);)
在的mapper后面的bean生命周期过程中,会进行实例化过程,也就是this.getSqlSession().getMapper(this.mapperInterface);–>getObject方法
因为MapperFactoryBean类实现了FactoryBean接口,这种实例化bean方式会通过调用MapperFactoryBean类中的getObject方法来实例化。
ClassPathMapperScanner:definition.setAutowireMode(2) 修改了自动注入状态,所以MapperFactoryBean中的setSqlSessionFactory会自动注入进去。
因为需要SqlSessionFactory,这就需要手动注入了(但是springboot会自动完成向spring容器注入SqlSessionFactory)
spring的xml方式整合mybatis的原理
面试:
SqlSessionFactoryBean:需要进行配置,用于提SqlSessionFactory;
MapperScannerConfigurer:需要进行配置,用于扫描指定mapper注册BeanDefinition;
MapperFactoryBean:Mapper的FactoryBean,获得指定Mapper时调用getObject方法;
ClassPathMapperScanner:definition.setAutowireMode(2) 修改了自动注入状态,所以
MapperFactoryBean中的setSqlSessionFactory会自动注入进去。