按需装配原理
由于上篇讲述了spring boot的自动装配原理。
而默认的自动装配组件不一定都全部加载,其原理是根据**“按需装配”**执行,即@conditionxxx 添加条件注解。
按需装配注解
- @ConditionalOnBean:当容器里有指定 Bean 的条件下
- @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
- @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
- @ConditionalOnClass:当类路径下有指定类的条件下
- @ConditionalOnMissingClass:当类路径下没有指定类的条件下
- @ConditionalOnProperty:指定的属性是否有指定的值
- @ConditionalOnResource:类路径是否有指定的值
- @ConditionalOnExpression:基于SpEL 表达式作为判断条件
- @ConditionalOnJava:基于 Java 版本作为判断条件
- @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
- @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
- @ConditionalOnWebApplication:当前项目是 Web 项 目的条件下
自动装配组件包
spring boot 自动装配组件所在的包为 spring-boot-autoconfigure-x.x.x.RELEASE.jar。
以WebMvcAutoConfiguration 配置为例,
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
public class WebMvcAutoConfiguration{}
1、@Configuration(proxyBeanMethods = false) ——标识该类为配置类,并使用轻量级lite模式,不使用代理加载类。
2、@ConditionalOnWebApplication(type = Type.SERVLET) ——当前环境是原生servlet时,才加载该组件。
值得一提的是,web应用分为原生式和响应式,响应式使用REACTIVE标识
3、@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class}) ——当这三个组件都加载后,才加载该组件。
4、@ConditionalOnMissingBean({WebMvcConfigurationSupport.class}) ——当IOC中不存在WebMvcConfigurationSupport组件时,才加载该组件。
若IOC已存在WebMvcConfigurationSupport组件,则代表IOC中已存在webMvc的配置或用户自定义了webMvc配置,此时就不应该加载该组件。 即,用户若自定义了组件,spring boot就不会在加载了,用户自定义组件优先。
5、@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class}) ——在这三个组件加载后加载。
@Bean
// 在IOC中不存在HiddenHttpMethodFilter组件时,才加载该组件
@ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
// application.yml配置中是否配置spring.mvc.hiddenmethod.filter.enabled ,若没有,则认为配置了false。则组件不加载
@ConditionalOnProperty(prefix = "spring.mvc.hiddenmethod.filter",name = {"enabled"},matchIfMissing = false)
public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
return new OrderedHiddenHttpMethodFilter();
}
@Bean
@ConditionalOnMissingBean({FormContentFilter.class})
// application.yml配置中是否配置spring.mvc.formcontent.filter.enabled ,若没有,则认为配置了true。则组件需要加载
@ConditionalOnProperty(prefix = "spring.mvc.formcontent.filter",name = {"enabled"},matchIfMissing = true)
public OrderedFormContentFilter formContentFilter() {
return new OrderedFormContentFilter();
}
与application.yml配置绑定
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
//开启与配置文件绑定
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}
1、WebMvcProperties.class
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
/**
* Locale to use. By default, this locale is overridden by the "Accept-Language"
* header.
*/
private Locale locale;
/**
* Whether to dispatch TRACE requests to the FrameworkServlet doService method.
*/
private boolean dispatchTraceRequest = false;
@ConfigurationProperties(prefix = “spring.mvc”)——与application.yml配置中的以spring.mvc为前缀的配置绑定。
该类下的所有的属性都和application.yml配置中prefix=spring.mvc的属性一一对应。如下所示:
spring:
mvc:
locale: zh_CN //与上述WebMvcProperties.locale对应
dispatch-trace-request: false //与上述WebMvcProperties.dispatchTraceRequest对应