1, springboot project the core is automatically loaded configuration, the function is dependent is a comment @SpringBootApplication in @EnableAutoConfiguration
2, EnableAutoConfiguration primarily to load class by AutoConfigurationImportSelector
In an example mybatis, * selector specified by reflection spring.factories loading java class, i.e. loading MybatisAutoConfiguration class (which has Configuration annotation category belongs to the configuration)
16 package org.mybatis.spring.boot.autoconfigure; 60 重点:SqlSessionFactory 和 SqlSessionTemplate 两个类
61 /**
62 * {@link EnableAutoConfiguration Auto-Configuration} for Mybatis. Contributes a
63 * {@link SqlSessionFactory} and a {@link SqlSessionTemplate}.
64 *
65 * If {@link org.mybatis.spring.annotation.MapperScan} is used, or a
66 * configuration file is specified as a property, those will be considered,
67 * otherwise this auto-configuration will attempt to register mappers based on
68 * the interface definitions in or under the root auto-configuration package.
69 *
70 * @author Eddú Meléndez
71 * @author Josh Long
72 * @author Kazuki Shimizu
73 * @author Eduardo Macarrón
74 */
75 @org.springframework.context.annotation.Configuration
76 @ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
77 @ConditionalOnBean(DataSource.class)
78 @EnableConfigurationProperties(MybatisProperties.class)
79 @AutoConfigureAfter(DataSourceAutoConfiguration.class)
80 public class MybatisAutoConfiguration {
81
82 private static final Logger logger = LoggerFactory.getLogger(MybatisAutoConfiguration.class);
83 //与mybatis配置文件对应
84 private final MybatisProperties properties;
85
86 private final Interceptor[] interceptors;
87
88 private final ResourceLoader resourceLoader;
89
90 private final DatabaseIdProvider databaseIdProvider;
91
92 private final List<ConfigurationCustomizer> configurationCustomizers;
93
94 public MybatisAutoConfiguration(MybatisProperties properties,
95 ObjectProvider<Interceptor[]> interceptorsProvider,
96 ResourceLoader resourceLoader,
97 ObjectProvider<DatabaseIdProvider> databaseIdProvider,
98 ObjectProvider<List<ConfigurationCustomizer>> configurationCustomizersProvider) {
99 this.properties = properties;
100 this.interceptors = interceptorsProvider.getIfAvailable();
101 this.resourceLoader = resourceLoader;
102 this.databaseIdProvider = databaseIdProvider.getIfAvailable();
103 this.configurationCustomizers = configurationCustomizersProvider.getIfAvailable();
104 }
105 //postConstruct作用是在创建类的时候先调用, 校验配置文件是否存在
106 @PostConstruct
107 public void checkConfigFileExists() {
108 if (this.properties.isCheckConfigLocation() && StringUtils.hasText(this.properties.getConfigLocation())) {
109 Resource resource = this.resourceLoader.getResource(this.properties.getConfigLocation());
110 Assert.state(resource.exists(), "Cannot find config location: " + resource
111 + " (please add config file or check your Mybatis configuration)");
112 }
113 }
114 //conditionalOnMissingBean作用:在没有类的时候调用,创建sqlsessionFactory sqlsessionfactory最主要的是创建并保存了Configuration类
115 @Bean
116 @ConditionalOnMissingBean
117 public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
118 SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
119 factory.setDataSource(dataSource);
120 factory.setVfs(SpringBootVFS.class);
121 if (StringUtils.hasText(this.properties.getConfigLocation())) {
122 factory.setConfigLocation(this.resourceLoader.getResource(this.properties.getConfigLocation()));
123 }
124 Configuration configuration = this.properties.getConfiguration();
125 if (configuration == null && !StringUtils.hasText(this.properties.getConfigLocation())) {
126 configuration = new Configuration();
127 }
128 if (configuration != null && !CollectionUtils.isEmpty(this.configurationCustomizers)) {
129 for (ConfigurationCustomizer customizer : this.configurationCustomizers) {
130 customizer.customize(configuration);
131 }
132 }
133 factory.setConfiguration(configuration);
134 if (this.properties.getConfigurationProperties() != null) {
135 factory.setConfigurationProperties(this.properties.getConfigurationProperties());
136 }
137 if (!ObjectUtils.isEmpty(this.interceptors)) {
138 factory.setPlugins(this.interceptors);
139 }
140 if (this.databaseIdProvider != null) {
141 factory.setDatabaseIdProvider(this.databaseIdProvider);
142 }
143 if (StringUtils.hasLength(this.properties.getTypeAliasesPackage())) {
144 factory.setTypeAliasesPackage(this.properties.getTypeAliasesPackage());
145 }
146 if (StringUtils.hasLength(this.properties.getTypeHandlersPackage())) {
147 factory.setTypeHandlersPackage(this.properties.getTypeHandlersPackage());
148 }
149 if (!ObjectUtils.isEmpty(this.properties.resolveMapperLocations())) {
150 factory.setMapperLocations(this.properties.resolveMapperLocations());
151 }
152
153 return factory.getObject();
154 }
155
156 @Bean
157 @ConditionalOnMissingBean
158 public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
159 ExecutorType executorType = this.properties.getExecutorType();
160 if (executorType != null) {
161 return new SqlSessionTemplate(sqlSessionFactory, executorType);
162 } else {
163 return new SqlSessionTemplate(sqlSessionFactory);
164 }
165 }
238 }
3、MybatisAutoConfiguration:
① There is a class MybatisProperties class, which corresponds to the profile mybatis
② class has a sqlSessionFactory method, it is to create SqlSessionFactory class, Configuration class (mybatis main categories, preserved things related to the mybatis)
③SelSessionTemplate, the role of the proxy class about mapperProoxy
4, attention MapperRegister class under Configuration in which this class is to create a dao (mapper proxy class), subsequent execution of dao specific query operations are based on the class
Below is springboot project started stack information:
1, springboot start calling the static method run SpringApplication
2, into the run: first carried out springboot related initialization
3, into the refreshContext method: the context initialization springboot
4, into the refresh method (the AbstractApplicationContext)
5, through the strength of a variety of bean beanfactory
。。。。
6, registered in ConfigurationClassBeanDefinitionReader class to load all of the classes specified in spring.facotrys
7、最后到MybatisAutoConfiguration的registerBeanDefinition方法中,并且在new classPathMapperScanner对象中会配置environment
8、通过ClassPathMapperScanner扫描mapper文件
9、进入scanner的doscan方法(其实调用的是父类的doScan方法)
10、进入父类ClassPathBeanDefinitionScanner类的doScan方法(其中basePackages就是application的包路径,这个包路径其实就是@springBootApplication注解中的一个主机ComponentScan类得到的)
11、在findCandidateComponents中返回Set集合(mapper类的集合)
。。。。
12、当springboot调用getBean方法是才是真正创建类的时候
13、最终到创建MybatisAutoConfiguration类了
在创建之前会调用checkConfigFileExists方法(因为方法上有@PostConstruct),校验mybatis配置文件是否存在
14、以上校验完之后,到注入属性
注入的时候通过beanname调用getbean方法来获取一个bean
15、在doGetBean方法中通过getSigngton(name)方法来获取已经注册过得bean,注册的bean都存在DefaultSingletonBeanRegister类的SingtonObjects的map对象中
另外该map对象中还存了这些bean:
SqlsessionFactory:
与事务相关的bean:
环境变量:
数据源配置bean:
sqlSessionTemplate:
等等。。。。
16, getbean eventually be obtained by MapperFactoryBean getObject method in which getSqlSession method returns SqlSessionTemplate, which is getMapper call is in SQLSessionTemplate
Methods
17, go to SqlSessionTemplage, getMapper class actually acquired from the Configuration object mapper
18, go to the Configuration, getMapper actually getting an object from MapperRegister
After 19, into MapperRegister in, getMapper from the map object knownMappers to get in, access to mapperProxyFactory, mapper factory to create a mapperProxy by newInstance
Proxy object
20, this mapperProxy is in use when the proxy class userdao
Reference Bowen: https://www.cnblogs.com/nxzblogs/p/10484281.html