跳至主要內容

Spring装配机制

pptg大约 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,延迟装配,做一些补充性工作