Springboot从手动装配到自动装配
先理解手动装配,再实现自动装配
模式注解(Stereotpe Annotations)
A stereotype annotation is an annotation that is used to declare the role that a component plays within the application. For example, the
@Repositoryannotation in the Spring Framework is a marker for any class that fulfills the role or stereotype of a repository (also known as Data Access Object or DAO).
@Componentis a generic stereotype for any Spring-managed component. Any component annotated with@Componentis a candidate for component scanning. Similarly, any component annotated with an annotation that is itself meta-annotated with@Componentis also a candidate for component scanning. For example,@Serviceis meta-annotated with@Component.
模式注解是一种用于声明在应用中扮演“组件”角色的注解。如 Spring Framework @Repository 标注在任何类上 ,用于扮演仓储角色的模式注解。@Component 作为一种由 Spring 容器托管的通用模式组件,任何被 @Component 标准的组件均为组件扫描的候选对象。类似地,凡是被 @Component 元标注(meta-annotated)的注解,如 @Service ,当任何组件标注它时,也被视作组件扫描的候选对象。
模式注解举例
| Spring Framework 注解 | 场景说明 | 起始版本 |
|---|---|---|
@Repository |
数据仓储模式注解 | 2.0 |
@Component |
通用组件模式注解 | 2.5 |
@Service |
服务模式注解 | 2.5 |
@Controller |
控制器模式注解 | 2.5 |
@Configuration |
配置类模式注解 | 3.0 |
装配方式
<context:component-scan> (配置文件)
@ComponentScan (用注解)
两个都可以设置要扫描的包 base-package
自定义模式注解
@Component “派生性”
@Component “层次性
1 |
|
1 |
|
@Component@Repository@FirstLevelRepository@SecondLevelRepository
所以被@SecondLevelRepository注解的类本质也是@Component
Spring @Enable 模块装配
@enable*是Springboot中用来启用某一个功能特性的一类注解。其中包括我们常用的@SpringBootApplication注解中用于开启自动注入的annotation@EnableAutoConfiguration,开启异步方法的annotation@EnableAsync,开启将配置文件中的属性以bean的方式注入到IOC容器的annotation@EnableConfigurationProperties等。
Spring Framework 3.1 开始支持”@Enable 模块驱动“。所谓“模块”是指具备相同领域的功能组件集合, 组合所形成一个独立 的单元。比如 Web MVC 模块、AspectJ代理模块、Caching(缓存)模块、JMX(Java 管 理扩展)模块、Async(异步处 理)模块等
@Enable 注解模块举例
| 框架实现 | @Enable注解模块 |
激活模块 |
|---|---|---|
| Spring Framework | @EnableWebMvc |
Web MVC 模块 |
@EnableTransactionManagement |
事务管理模块 | |
@EnableCaching |
Caching 模块 | |
@EnableMBeanExport |
JMX 模块 | |
@EnableAsync |
异步处理模块 | |
@EnableWebFlux |
Web Flux 模块 | |
@EnableAspectJAutoProxy |
AspectJ 代理模块 | |
| Spring Boot | @EnableAutoConfiguration |
自动装配模块 |
@EnableManagementContext |
Actuator 管理模块 | |
@EnableConfigurationProperties |
配置属性绑定模块 | |
@EnableOAuth2Sso |
OAuth2 单点登录模块 | |
| Spring Cloud | @EnableEurekaServer |
Eureka服务器模块 |
@EnableConfigServer |
配置服务器模块 | |
@EnableFeignClients |
Feign客户端模块 | |
@EnableZuulProxy |
服务网关 Zuul 模块 | |
@EnableCircuitBreaker |
服务熔断模块 |
实现方式
注解驱动方式
以SpringMvc为例:@EnableWebMvc注解有个@Import指向了DelegatingWebMvcConfiguration类,不够灵活
1 |
|
1 |
|
接口编程方式
@EnableCaching 注解中@Import指向一个ImportSelector接口的实现类,这个接口只需要重写selectImports这个方法,可以在方法里写判断,能灵活的返回一个String[]
1 |
|
1 | public class CachingConfigurationSelector extends AdviceModeImportSelector<EnableCaching> { |
自定义@Enable 模块
基于注解驱动实现 - @EnableHelloWorld
不详写
基于接口驱动实现 - @EnableHelloWorld
@EnableHelloWorld->HelloWorldImportSelector ->HelloWorldConfiguration ->helloWorld
准备一个helloWorld的Bean
1 | public class HelloWorldConfiguration { |
自定义一个helloworld的选择器继承ImportSelector,实现接口方法,返回上面的Bean
1 | public class HelloWorldImportSelector implements ImportSelector { |
自定义个 @EnableHelloWorld 注解,@Import指向自定义的HelloWorldImportSelector
1 |
|
在启动类加上@EnableHelloWorld,就可以使用helloworld这个Bean了
1 |
|
Spring 条件装配
从 Spring Framework 3.1 开始,允许在 Bean 装配时增加前置条件判断。spring条件装配实现主要有两种实现方式,一种是配置化条件装配,使用
@Profile注解来实现。另一种比较灵活,底层实现Condition接口来进行实现。
条件注解举例
| Spring 注解 | 场景说明 | 起始版本 |
|---|---|---|
| @Profile | 配置化条件装配(不灵活,条件单一) | 3.1 |
| @Conditional | 编程条件装配(灵活) | 4.0 |
自定义条件装配
配置方式- @Profile
1 | //定义一个计算接口 |
编程方式- @Conditional
自定义@ConditionalOnSystemProperty注解,指向OnSystemPropertyCondition.class,这是我们自定义的一个类,
1 |
|
必须要实现Condition接口,重写matches方法,这里用AnnotatedTypeMetadata获取注解的元信息,取出来后比较和System里配置的值是否相等
1 | public class OnSystemPropertyCondition implements Condition { |
在启动类中测试,@ConditionalOnSystemProperty注解了helloWorld这个Bean,当系统用户名和10418相等的时候就装载这个Bean
1 | public class ConditionalOnSystemPropertyBootstrap { |
Spring Boot 自动装配
在 Spring Boot 场景下,基于约定大于配置的原则,实现 Spring 组件自动装配的目的。其中使用了
底层装配技术
- Spring 模式注解装配
- Spring
@Enable模块装配 - Spring 条件装配装配
- Spring 工厂加载机制
- 实现类:
SpringFactoriesLoader - 配置资源:
META-INF/spring.factories
- 实现类:
自动装配举例
参考 META-INF/spring.factories idea中搜索
实现方法
激活自动装配 -
@EnableAutoConfiguration一旦加上此注解,那么将会开启自动装配功能,简单点讲,Spring会试图在你的classpath下找到所有配置的Bean然后进行装配。当然装配Bean时,会根据若干个(Conditional)定制规则来进行初始化。
实现自动装配 -
XXXAutoConfiguration配置自动装配实现 -
META-INF/spring.factories
自定义自动装配
创建一个自动配置类,@EnableHelloWorld基于上面的自定义的@Enable模块,@ConditionalOnSystemProperty 同上
1 |
|
在classpath目录下的META-INF/spring.factories配置好自动装配
1 | # Auto Configure |
启动类开启@EnableAutoConfiguration测试
1 |
|
HelloWorldAutoConfiguration
条件判断:
user.name == "10418"模式注解:
@Configuration@Enable模块:@EnableHelloWorld->HelloWorldImportSelector->HelloWorldConfiguration- >helloWorld