1、Spring Beans和依赖注入
我们可以自由使用任何标准的Spring Framework技术来定义bean及其注入的依赖项。为简单起见,通常使用@ComponentScan
(查找您的bean)和使用@Autowired
(进行构造函数注入)。
如果将应用程序类放在根包中,则可以添加@ComponentScan
而无需任何参数,并且所有的应用 程序组件(的@Component
,@Service
,@Repository
,@Controller
等)自动注册为Spring Beans
。
以下示例显示了一个@Service
使用构造函数注入来获取所需RiskAssessor
Bean的Bean:
package com.example.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
如果bean具有一个构造函数,则可以省略@Autowired,如以下示例所示:
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
2、使用@SpringBootApplication注释
许多Spring Boot开发人员喜欢他们的应用程序使用自动配置,组件扫描,并能够在其“应用程序类”上定义额外的配置。单个@SpringBootApplication
注释可用于启用这三个功能,即:
- @EnableAutoConfiguration:启用Spring Boot的自动配置机制
- @ComponentScan:启用@Component对应用程序所在的软件包的扫描
- @Configuration:允许在上下文中注册额外的bean或导入其他配置类
@SpringBootApplication还提供了别名定制的属性@EnableAutoConfiguration和@ComponentScan。
3、@ComponentScan自动扫描组件
3.1 创建一个配置类,在配置类上添加 @ComponentScan 注解。该注解默认会扫描该类所在的包下所有的配置类,相当于之前的 context:component-scan。
3.2 指定要扫描的包(使用@ComponentScan 的 valule 属性来配置)
例如:
package io.mieux.config;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(value = "io.mieux.controller")
public class BeanConfig {
}
3.3 使用 excludeFilters 来按照规则排除某些包的扫描。
package io.mieux.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@ComponentScan(value = "io.mieux",
excludeFilters = {@Filter(type = FilterType.ANNOTATION,
value = {Controller.class})})
public class BeanConfig {
}
excludeFilters 的参数是一个 Filter[] 数组,然后指定 FilterType 的类型为 ANNOTATION,也就是通过注解来过滤,最后的 value 则是Controller 注解类。配置之后,在 spring 扫描的时候,就会跳过 io.mieux 包下,所有被 @Controller 注解标注的类。
3.4 使用 includeFilters 来按照规则只包含某些包的扫描。
package io.mieux.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
@ComponentScan(value = "io.mieux", includeFilters = {@Filter(type = FilterType.ANNOTATION, classes = {Controller.class})})
public class BeanConfig {
}
此时,只包含 @Controller 注解的类才会被注册到容器中,但是要注意:此时,加@Service
注解的类一样会被注册到容器中,这涉及到 @ComponentScan
的一个 useDefaultFilters
属性的用法,该属性默认值为 true,也就是说 spring 默认会自动发现被 @Component
、@Repository
、@Service
和 @Controller
标注的类,并注册进容器中。要达到只包含某些包的扫描效果,就必须将这个默认行为给禁用掉(在 @ComponentScan 中将 useDefaultFilters 设为 false 即可)。
3.5 添加多种扫描规则
1)如果使用的 jdk8,则可以直接添加多个 @ComponentScan 来添加多个扫描规则,但是在配置类中要加上 @Configuration 注解,否则无效。
package io.mieux.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@ComponentScan(value = "io.mieux.controller")
@ComponentScan(value = "io.mieux.service")
@Configuration
public class BeanConfig {
}
2)也可以使用 @ComponentScans 来添加多个 @ComponentScan,从而实现添加多个扫描规则。同样,也需要加上 @Configuration 注解,否则无效。
package io.mieux.config;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScans;
import org.springframework.context.annotation.Configuration;
@ComponentScans(value =
{@ComponentScan(value = "io.mieux.controller"),
@ComponentScan(value = "io.mieux.service")})
@Configuration
public class BeanConfig {
}
4、@EnableAutoConfiguration(自动配置)
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
@Import(AutoConfigurationImportSelector.class),借助AutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IOC容器。
借助Spring框架原有的一个工具类:SpringFactoriesLoader的支持,@EnableAutoConfiguration可以智能的自动配置功效才得以大功告成。
把AutoConfigurationImportSelector类中可以看到通过 SpringFactoriesLoader.loadFactoryNames()
在这个注解中,最重要的是它导入了一个类EnableAutoConfigurationImportSelector
它是一个ImportSelector
接口的实现类,而ImportSelector接口中的selectImports方法所返回的类将被Spring容器管理起来。
5、springboot底层实现自动配置的步骤:
1.springboot应用启动
2.@SpringBootApplication起作用
3.@EnableAutoConfiguration
4.@AutoConfigurationPackage:这个组合注解主要是@Import(AutoConfigurationPackages.Registrar.class),它通过将Registrar类导入到容器中,而Registrar类作用是扫描主配置类同级目录以及子包,并将相应的组件导入到springboot创建管理的容器中
5.@Import(AutoConfigurationImportSelector.class):它通过将AutoConfigurationImportSelector类导入到容器中,AutoConfigurationImportSelector类作用是通过selectImports方法实现将配置类信息交给SpringFactory加载器进行一系列的容器创建过程