一、 SpringBoot starter机制
统一管理,统一引入 减少繁琐配置,解决版本冲突
二、 自定义starter
1.开发中有很多独立于业务的配置模块,重复引用的时候在pom中引用即可使用。
例如:
- 动态数据源。
- 登录模块。
- 基于AOP技术实现日志切面。
......
2.自定义starter的命名规则
- SpringBoot提供的starter以spring-boot-starter-xxx 的方式命名的。
- 官方建议自定义的starter使用xxx-spring-boot-starter 命名规则。以区分SpringBoot生态提供
的starter
3.实现
3.1 新建maven jar工程,工程名为ldz-spring-boot-starter,导入依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.2.9.RELEASE</version>
</dependency>
</dependencies>
自动配置的核心依赖
3.2 编写javaBean实体
@EnableConfigurationProperties(SimpleBean.class)
@ConfigurationProperties(prefix = "simplebean")
public class SimpleBean {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "SimpleBean{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}
通用的配置类实体(在调用的工程中配置调用的属性值)
3.3 编写配置类MyAutoConfiguration
@Configuration
public class MyAutoConfiguration {
static {
System.out.println("MyAutoConfiguration init....");
}
@Bean
public SimpleBean simpleBean(){
return new SimpleBean();
}
}
实例化通用Javabean的类,这个类实例化的时候@Bean方法的结果会作为spring的bean放到ioc容器中,交由spring管理.
3.4 resources下创建/META-INF/spring.factories
META-INF是自己手动创建的目录,spring.factories也是手动创建的文件,在该文件中配置自
己的自动配置类
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.lagou.config.MyAutoConfiguration
spring启动的时候会根据key:org.springframework.boot.autoconfigure.EnableAutoConfiguration加载/META-INF/spring.factories下的value,然后实例化,并且执行@bean方法,进行配置bean的实例化。
4. 使用自定义starter
4.1 导入自定义starter的依赖
<dependency>
<groupId>com.lagou</groupId>
<artifactId>ldz-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
4.2 在全局配置文件中配置属性值
simplebean.id=1
simplebean.name=自定义starter
4.2 测试
//测试自定义starter
@Autowired
private SimpleBean simpleBean;
@Test
public void zdyStarterTest(){
System.out.println(simpleBean);
}
三、 如果有一天我们不想要启动工程的时候自动装配SimpleBean
1. 删除pom.xml中的依赖 (low)
2. 热插拔技术
我们经常会在启动类Application上面加@EnableXXX注解,其实这个@Enablexxx注解就是一种热拔插技术,加了这个注解就可以启动对应的starter,当不需要对应的starter的时候只需要把这个注解注释掉就行。
2.1 改造ldz工程新增热插拔支持类
2.1.1 新增标记类ConfigMarker
public class ConfigMarker {
}
2.1.2 新增EnableRegisterServer注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Import({ConfigMarker.class})
public @interface EnableRegisterServer {
}
2.1.3 改造MyAutoConfiguration
新增条件注解@ConditionalOnBean(ConfigMarker.class) ,
@ConditionalOnBean 这个是条件注解,前面的意思代表只有当期上下文中含有ConfigMarker对象,被标注的类才会被实例化。
@Configuration
@ConditionalOnBean(ConfigMarker.class)
public class MyAutoConfiguration {
static {
System.out.println("MyAutoConfiguration init....");
}
@Bean
public SimpleBean simpleBean(){
return new SimpleBean();
}
}
2.1.4 改造调用工程
在启动类上新增@EnableImRegisterServer注解
当加了@EnableImRegisterServer 的时候启动zdy工程就会自动装配SimpleBean,反之则不装配。
2.1.4 原理
当加了@EnableImRegisterServer 注解的时候,由于这个注解使用了@Import({ConfigMarker.class}) ,所以会导致Spring去加载ConfigMarker 到上下文中,而又因为条件注@ConditionalOnBean(ConfigMarker.class) 的存在,所以MyAutoConfiguration 类就会被实例化。
3 关于条件注解的讲解
- @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
- @ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。
- @ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。基于SpEL表
达式的条件判断。 - @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个
Bean。 - @ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
- @ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
- @ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
- @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
- @ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
- @ConditionalOnResource:当类路径下有指定的资源时触发实例化。
- @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
- @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定
了首选的Bean时触发实例化。