SpringBoot 之 Starter
Spring Boot Starter 是一组可重用的依赖库,它们提供了一种快速启动 Spring Boot 应用程序的方式。每个 Starter 都包含了一组预配置的依赖项和自动配置类,使得使用者可以轻松地集成各种不同的功能模块,而无需手动配置大量的依赖项和参数。这样,开发人员可以更加专注于业务逻辑的实现,而不需要关心底层的配置和集成细节。
Spring Boot Starter 的意义在于减少了应用程序的开发成本和复杂度,提高了开发效率和代码质量,并且支持更快的迭代和部署。另外,社区也提供了很多常用的 Starter,如数据库、Web 框架、安全框架等,可以直接使用,也可以通过定制来满足具体的需求。
# 一、starter 依赖
新建一个 spring boot 工程。
<!-- 包含了log 以及 autoconfigure 等 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- 对 @ConfigurationProperties 的处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
2
3
4
5
6
7
8
9
10
11
# 二、添加配置类
package com.xianwt.cloud.properties;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @Author big uncle
* @Date 2019/11/27 9:27
**/
@ConfigurationProperties(prefix = "security.authentication")
@Data
public class AuthenticationProperties {
/**
* token
**/
private String userToken = "USER:TOKEN:";
/**
* 拦截
**/
private String authorization = "Authorization";
/**
* 默认参数用户
**/
private String userKey = "default:user:";
/**
* 权限
**/
private String authorityKey = "USER:AUTHORITY:";
/**
* 用户访问资源锁 默认不拦截
**/
private Boolean authorityLock = false;
/**
* 项目过滤集合, 以逗号分割
**/
private List<String> projectUrl;
/**
* 特殊路径放弃拦截,走非 RequestData 方式
**/
private List<String> specialUrl;
/**
* 失败处理器
**/
private String failureUrl = "/failure/authenticationFilter";
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# 添加加载类
package com.xianwt.cloud.properties;
/**
* @Author big uncle
* @Date 2020/3/29 10:58
* @module
**/
import com.xianwt.cloud.cep.AuthenticationCep;
import com.xianwt.cloud.cep.AuthorizationCep;
import com.xianwt.cloud.cep.ProjectUrlFilterCep;
import com.xianwt.cloud.cep.SpecialFilterCep;
import com.xianwt.cloud.cep.impl.AuthenticationCepImpl;
import com.xianwt.cloud.cep.impl.AuthorizationCepImpl;
import com.xianwt.cloud.cep.impl.ProjectUrlFilterCepImpl;
import com.xianwt.cloud.cep.impl.SpecialFilterCepImpl;
import com.xianwt.cloud.filter.AuthenticationFilter;
import com.xianwt.cloud.server.AuthenticationServerSource;
import com.xianwt.cloud.server.AuthorizationServerSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.annotation.Resource;
@Configuration
@EnableConfigurationProperties({AuthenticationProperties.class})
public class AuthenticationConfiguration {
private static final Log log = LogFactory.getLog(AuthenticationFilter.class);
@Autowired
private AuthenticationProperties authenticationProperties;
public ProjectUrlFilterCep projectUrlFilterCep(){
return new ProjectUrlFilterCepImpl(authenticationProperties);
}
public SpecialFilterCep specialFilterCep(){
return new SpecialFilterCepImpl(authenticationProperties);
}
@Bean
public AuthenticationCep authenticationCep(AuthenticationServerSource authenticationServerSource){
AuthenticationCepImpl authenticationCep = new AuthenticationCepImpl(authenticationProperties,authenticationServerSource);
return authenticationCep;
}
@Bean
public AuthorizationCep authorizationCep(AuthorizationServerSource authorizationServerSource){
AuthorizationCepImpl authenticationCep = new AuthorizationCepImpl(authenticationProperties,authorizationServerSource);
return authenticationCep;
}
@Bean
public FilterRegistrationBean<AuthenticationFilter> testFilterRegistration(AuthenticationCep authenticationCep,AuthorizationCep authorizationCep) {
FilterRegistrationBean<AuthenticationFilter> registration = new FilterRegistrationBean<>();
AuthenticationFilter authenticationFilter = AuthenticationFilter.builder()
.authenticationProperties(authenticationProperties)
.specialFilterCep(specialFilterCep())
.projectUrlFilterCep(projectUrlFilterCep())
.authenticationCep(authenticationCep)
.authorizationCep(authorizationCep)
.build();
registration.setFilter(authenticationFilter);
//配置过滤路径
registration.addUrlPatterns("/*");
//设置filter名称
registration.setName("authenticationFilter");
//请求中过滤器执行的先后顺序,值越小越先执行
registration.setOrder(1);
return registration;
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
最主要得就是注解,至于业务逻辑大家都是写自己得。
# 四、指定加载文件路径
在 resources 目录下新建 META-INF 文件夹,在 META-INF 文件夹下在新建 spring.factories 文件,且在文添加以下内容
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.xianwt.cloud.properties.AuthenticationConfiguration
2
不出问题大家发布后,在别的项目依赖自己的 jar 就可以了。但除了 EnableAutoConfiguration 外还有其他的一些类可以共我们使用:
- EnableAutoConfiguration:指定自动配置类,启动会执行指定的类。
- ApplicationContextInitializer:初始化应用程序上下文的回调接口,可以帮助我们拿到 applicationContext。
- ApplicationListener:监听应用程序事件的回调接口,这里可以监听 ContextRefreshedEvent 当应用程序上下文被初始化或刷新时触发;ApplicationStartedEvent 当 Spring 应用程序上下文准备完毕后,但尚未运行时触发;ApplicationReadyEvent 当应用程序已经启动并准备好服务请求时触发;ContextClosedEvent 当应用程序上下文关闭时触发;也可以触发我们的自定义事件。
- ConditionContributor:为自动配置提供额外的条件,可以用 @ConditionalOnProperty 来代替。
- TemplateAvailabilityProvider:在运行时检查可用模板的策略接口,使用它们来确定是否存在正确的模板文件。
# 五、介绍下其他条件装配注解
@ConditionalOnBean 在当前上下文中存在某个对象时,才会实例化一个 Bean
@ConditionalOnMissingBean 在当前上下文中不存在某个对象时,才会实例化一个 Bean
@Conditiona lOnClass 表示当 class path 有指定的类时,配置生效。
@ConditionalOnMissingClass 表示当 classpath 中没有指定的类的时候,配置生效。
@ConditionalOnProperty 注解根据 name 来读取 Spring Boot 的 Environment 的 变量包含的属性,根据其值与 havingValue 的值比较结果决定配置是否生效。如果没有指定 havingValue ,只要属性不为 false ,配置都能生效。matcblfMissing 为例 意味着如果 Environment 没有包含 “message.center.enabled”,配置也能生效,默认为 false。
@ConditionalOnExpression ,当表达式为 true 时,才会实例化一个 Bean ,支持 SpEL 表达式,比如根据配置文件中的某个值来决定配置是否生效。
@ConditionalOnJava ,当存在指定的 Java 版本的时候。
# 六、升级到 SpringBoot3 使用 starter
在 SpringBoot2.7 就已经说明建议使用 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 的方式作为定义自动装配文件位置。而在 3.0 版本,已经是移除了 META-INF/spring.factories,所以我们继续通过 META-INF/spring.factories 文件定义将不在生效。
<!-- 添加依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<!-- 对 @ConfigurationProperties 的处理 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
2
3
4
5
6
7
8
9
10
11
@AutoConfiguration
@EnableConfigurationProperties(value = TestProperties.class)
public class TestAutoConfiguration {
@Bean
public TestTemplate testTemplate(){
return new TestTemplate ();
}
}
2
3
4
5
6
7
8
9
10
@AutoConfiguration 是 spring boot2.7 新引入的,自动配置类必须放进下面的文件里才算自动配置类
在 META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 文件里面添加
com.spring.demo.test.TestAutoConfiguration