Springboot自动配置和自定义自动配置
自动配置: 常用框架对应的JavaConfig类都已经编写好了,springboot启动的时候会一个一个的进行读取,读取时会先根据条件注解进行判断,看是否满足条件,满足条件后才会读取配置类然后去配置对应的框架。
- Springboot启动后,读取程序的启动类时,就会读取到@SpringBootApplication注解
- @SpringBootApplication注解又包含了 @EnableAutoConfiguration注解
- @EnableAutoConfiguration注解导入了AutoConfigurationImportSelector类, 即@Import(AutoConfigurationImportSelector.class)
- AutoConfigurationImportSelector.class中,定义了一个方法getCandidateConfigurations,进入getCandidateConfigurations方法,getCandidateConfigurations会到classpath下的读取META-INF/spring.factories文件的配置
- spring.factories文件在spring-boot-autoconfigure-2.3.0.RELEASE.jar的META-INF中,spring.factories文件中声明了很多java配置类,但是每个配置类都是需要满足一定的条件才会执行(例如: @ConditionalOnClass 、 @ConditionalOnProperty、 @ConditionalOnMissingBean等)。
自定义自动配置类
自己创建一个配置列,然后写一个接口和实现了这个接口的默认类,在resoureces下创建META-INF/spring.factories,程序启动后就会加载配置类文件,从而加载配置类,完成自动配置。
resoureces/META-INF/spring.factories,加载这个文件就会去加载里面的配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration= com.spring.autoconfig.config.MyAutoConfiguration
配置类MyAutoConfiguration.java,当扫描到这个类时,会扫描到@ConditionalOnMissingBean(UserService.class)注解,然后就会去判断容器种有没有这个类,如果没有,则满足条件才会继续加载下面的配置。
package com.spring.autoconfig.config; import com.spring.autoconfig.service.DefaultUserServiceImpl; import com.spring.autoconfig.service.UserService; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration @ConditionalOnMissingBean(UserService.class) // 条件:没有这个class类型才加载 public class MyAutoConfiguration { @Bean public UserService getUserService() { return new DefaultUserServiceImpl(); } }
接口UserService.java
package com.spring.autoconfig.service; public interface UserService { void save(); }
接口实现类DefaultUserServiceImpl.java
package com.spring.autoconfig.service; public class DefaultUserServiceImpl implements UserService { @Override public void save() { System.out.println("save success"); } }
在测试类中直接注入UserService,判断是否注入成功,如下图可知,注入成功,调用了sava方法打印了成功的输出语句。