Spring装配机制
大约 2 分钟
1. 手动装配
// xml
<bean id="xxx" class="xxx"/>
// 注解配置类
@Configuration
public class XXXConfiguration{}
// 组件扫描
@Component
public class XXXComponent{}
@Configuration
@ComponentScan("xxx.xxx.xxx")
public class XXXConfiguration{}
2. 自动装配
2.1 组件装配
组件装配:将第三方技术的核心API配置到XML配置文件或注解配置类的行为。SpringBoot通过模块装配+条件装配+SPI机制,对Spring Framework进行了增强,将组件自动装配到IOC容器(ApplicationContext)中。
2.2 模块装配
模块装配:自动装配的核心,把一个模块的核心功能组件都装配到IOC中
在@Import中可以导入:
- 普通类
- 配置类
- ImportSelector类
通过这些,可以把需要组合的多个组件都封装到一个Enable的注解中,进而达到模块装配的效果
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Import({Boss.class, BartenderConfiguration.class, ...})
public @interface EnableTavern {
}
2.3 条件装配
2.3.1 @Profile
// 只有在这个条件激活时才会生效
@profile("xxx")
使用profile方法:
- 在application.properties中配置
spring.profiles.active=dev
, 此时application-dev.properties将会生效 - 在启动时添加
-Dspring.profiles.active=dev
- 在代码中
applicationContext.getEnvironment.setActiveProfiles("dev")
但因为要修改代码,不太优雅
2.3.2 @Conditional
// 只有xxx的条件符合时,被注解的对象才会生效
@Conditional(xxx)
// 其他@ConditionalOnXXX的注解,尽量用在自动配置类上,不要用在普通的配置类,避免出现判断偏差
@ConditionalOnClass // 是否包含指定类
@ConditionalOnBean // 是否注册了Bean
@ConditionalOnProperty // 检查属性配置
@ConditionalOnWebApplication // 是否web应用
@ConditionalOnExpression // 是否满足表达式
2.4 SPI
2.4.1 JDK的SPI
多个类实现同一接口之后,将SPI文件放入META-INF/services下,命名为全限定名,并在文件内放入想要装配的具体实现类全限定名,最后通过以下方法调用:
ServiceLoader<XXX> loader = ServiceLoader.Load(XXX.class);
2.5 SpringBoot的自动装配
SpringBoot的主启动类使用@SpringBootApplication标注,会触发@EnableAutoConfiguration自动装配和@ComponentScan自动扫描
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan()
public @interface SpringBootApplication {}
2.5.1 @ComponentScan
@ComponentScan用于扫描主启动类及其包下所有的组件, 但此处添加了两个过滤:
- TypeExcludeFilter: 提供自定义过滤器,向IOC注册TypeExcludeFilter的子类即可
- AutoConfigurationExcludeFilter: 过滤掉自动装配的类
@ComponentScan(
excludeFilters = {@Filter(
type = FilterType.CUSTOM,
classes = {TypeExcludeFilter.class}
), @Filter(
type = FilterType.CUSTOM,
classes = {AutoConfigurationExcludeFilter.class}
)}
)
2.5.2 @SpringBootConfiguration
等同于Configuration,代表是一个注解配置类,此外,在spring-boot-starter-test
的测试中被调用,被用来进行测试
@Configuration
public @interface SpringBootConfiguration {}
2.5.3 @EnableAutoConfiguration
该注解会开启自动装配,根据导入的依赖、上下文配置加载默认的自动配置
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})·
public @interface EnableAutoConfiguration {}
同时该注解包含了两个注解,作用如下:
- @AutoConfigurationPackage: 记录主启动类所在的包,注册到AutoConfigurationPackages中
- @AutoConfigurationImportSelector:实现了DeferredImportSelector,延迟装配,做一些补充性工作