向我的偶像,最牛程序员 Tony Stark(1970-2019) 致敬!
<repositories>
<repository>
<id>eastsoft-snapshots</id>
<name>Eastsoft Snapshots</name>
<url>http://218.58.62.115:18081/nexus/repository/snapshots/</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<!-- 公共方法包 -->
<dependency>
<groupId>com.stark.commons</groupId>
<artifactId>commons-lang</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
<!-- Spring 核心配置 -->
<dependency>
<groupId>com.stark.commons</groupId>
<artifactId>commons-spring-core</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
<!-- Spring Web 配置 -->
<dependency>
<groupId>com.stark.commons</groupId>
<artifactId>commons-spring-web</artifactId>
<version>1.1.0-SNAPSHOT</version>
</dependency>
yml
中指定 spring.datasource.multiple=true
,开启自动配置spring:
datasource:
multiple: true
yml
中配置多数据源spring:
datasource:
druid:
ds1:
driver-class-name: net.sourceforge.jtds.jdbc.Driver
url: jdbc:jtds:sybase://129.1.50.194:8888/escloud;charset=cp936
username: escloud
password: fpSPcx5kfoNl+aZalQQcaJq0WQ3OkikNzYjBpUquEQEpCEg6AxJZWZMyts1YPIn97PYD3843FQh8j/7xdSE7Eg==
initial-size: 10
min-idle: 10
max-active: 20
keep-alive: true
validation-query: select count(*) from S_COURT
validation-query-timeout: 0
filters: config,stat,slf4j
connection-properties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIxnQJmAfL8vCTtuKViDH5FVEPC5Ao1gNOsBHgv+e6ccWV5CLJoAy1+pZPW5RWGCFYikTg6Q11oCUuC6kJAW0GcCAwEAAQ==
ds2:
driver-class-name: net.sourceforge.jtds.jdbc.Driver
url: jdbc:jtds:sybase://129.1.50.194:8888/escourt6;charset=cp936
username: escourt6
password: fpSPcx5kfoNl+aZalQQcaJq0WQ3OkikNzYjBpUquEQEpCEg6AxJZWZMyts1YPIn97PYD3843FQh8j/7xdSE7Eg==
initial-size: 10
min-idle: 10
max-active: 20
validation-query: select count(*) from S_COURT
validation-query-timeout: 0
filters: config,stat,slf4j
connection-properties: config.decrypt=true;config.decrypt.key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBAIxnQJmAfL8vCTtuKViDH5FVEPC5Ao1gNOsBHgv+e6ccWV5CLJoAy1+pZPW5RWGCFYikTg6Q11oCUuC6kJAW0GcCAwEAAQ==
web-stat-filter:
enabled: true
url-pattern: /*
exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'
stat-view-servlet:
enabled: true
url-pattern: /druid/*
login-username: eastsoft
login-password: eastsoft.cn
com.stark.commons.spring.core.support.sql.RoutingDataSource
接口,返回数据源 bean@Configuration
public class DataSourcesConfig {
@Bean
@ConfigurationProperties("spring.datasource.druid.ds1")
public RoutingDataSource escloudDataSource() {
DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
return new DruidRoutingDataSource(druidDataSource, "ds1", true);
}
@Bean
@ConfigurationProperties("spring.datasource.druid.ds2")
public RoutingDataSource esshare6DataSource() {
DruidDataSource druidDataSource = DruidDataSourceBuilder.create().build();
return new DruidRoutingDataSource(druidDataSource, "ds2", false);
}
}
@DataSource("lookupKey")
注解切换数据源public class DataSourcesConfig {
@DataSource("ds2")
public void function() {
// ...
}
}
@DataSource("ds2")
public class DataSourcesConfig {
public void function1() {
// ...
}
public void function2() {
// ...
}
}
yml
配置spring:
transaction:
aop:
base-packages: com.stark.demo.service.impl # 显示指定包扫描位置,开启自动配置
read-only-methods: get*,find*,query*,select*,count* # 只读事务方法,支持通配符,多个以 "," 隔开,默认值 ""
required-methods: insert*,add*,save*,update*,delete*,remove* # 写事务方法,支持通配符,多个以 "," 隔开,默认值 "*"
timeout: -1 # 超时回滚时间,默认值 -1 不回滚
@Transactional
和 @NonTransactional
注解的方法,事务按照注解的逻辑执行,不受切面控制@NonTransactional
等同于 @Transactional(propagation = Propagation.NOT_SUPPORTED)
10ms
的时间@NonTransactional
或 @Transactional(propagation = Propagation.NOT_SUPPORTED)
注解关闭事务spring.transaction.aop.read-only-methods
和 spring.transaction.aop.required-methods
的约定定义方法名spring-boot-starter-jta-atomikos
包;<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
<version>${springboot.version}</version>
</dependency>
yml
中指定 spring.jta.enabled=true
,开启自动配置spring:
jta:
enabled: true # 显示指定 true ,开启自动配置
log-dir: ./ # 日志文件目录
@Transactional
注解用户 user 、用户信息 userInfo 在一个事务,部门 dept 在一个事务,两个事务相互独立。
@Service("userService")
public class UserService {
@Autowired
private UserInfoService userInfoService;
@Autowired
private DeptService deptService;
// 事务切面织入事务
public void add(User user, UserInfo userInfo, Dept dept) {
// 通过 @Transactional(propagation = Propagation.REQUIRES_NEW) 新起事务
userInfoService.addUserAndUserInfo(user, userInfo);
// 继承父方法的事务
deptService.add(dept);
}
}
@Service("userInfoService")
public class UserInfoService {
@Autowired
private UserRepository userRepository;
@Autowired
private UserInfoRepository userInfoRepository;
// 新起一个事务
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void addUserAndUserInfo(User user, UserInfo userInfo) {
userRepository.save(user);
userInfoRepository.save(userInfo);
}
}
@Service("deptService")
public class DeptService {
@Autowired
private DeptRepository deptRepository;
// 事务切面织入事务
public void add(Dept dept) {
deptRepository.save(dept);
}
}
Elasticsearch 6.8 和 7.1 以上。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>${springboot.version}</version>
<exclusions>
<exclusion>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>x-pack-transport</artifactId>
<version>${elasticsearch.version}</version>
</dependency>
yml
中配置:spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: es1.stark.com:9300,es2.stark.com:9300
xpack:
security-transport-ssl-enabled: true
security-user: elastic
security-password: 123456
ssl-verification-mode: certificate
ssl-keystore-path: classpath:certs/dev-qd/elastic-certificates.p12
ssl-truststore-path: classpath:certs/dev-qd/elastic-certificates.p12
ssl-keystore-password: 123456
ssl-truststore-password: 123456
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-elasticsearch</artifactId>
<version>${springboot.version}</version>
</dependency>
<dependency>
<groupId>com.floragunn</groupId>
<artifactId>search-guard-ssl</artifactId>
<version>${elasticsearch.version}-25.6</version>
</dependency>
yml
中配置:spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: es1.stark.com:9300,es2.stark.com:9300
search-guard:
ssl-transport-pemtrustedcas-filepath: classpath:elk/dev/root-ca.pem
ssl-transport-pemcert-filepath: classpath:elk/dev/elk-server.pem
ssl-transport-pemkey-filepath: classpath:elk/dev/elk-server.key
ssl-transport-pemkey-password: 123456
elasticsearch
、 transport
、 search-guard-ssl
三者版本必须一致!@EnableAspectJAutoProxy
开启切面注解支持;com.stark.commons.spring.core.support.log.LogService
接口,开启日志切面自动配置;@Log(type = {int}, businessKey = "{String}", message = "{String}")
注解, String
类型参数支持 spel
表达式。@Service
public class UserService {
@Log(type = LogType.TABLE_INSERT, businessKey = "#user.id", message = "'新增用户:id=' + #user.id")
public User add(User user) {
// ...
}
@Log(type = LogType.TABLE_DELETE, businessKey = "#id", message = "'删除用户:id=' + #id")
public int delete(Long id) {
// ...
}
@Log(type = LogType.TABLE_UPDATE, businessKey = "#user.id", message = "'修改用户:id=' + #user.id")
public User update(User user) {
// ...
}
@Log(type = LogType.TABLE_SELECT, businessKey = "#id", message = "'查询用户:id=' + #p0")
public User get(Long id) {
// ...
}
}
yml
配置
spring:
task:
execution: # 任务执行器,多线程操作使用
thread-name-prefix: task- # 线程名前缀,打印日志时使用
pool:
core-size: 8 # 核心线程数,默认 8
max-size: 2147483647 # 最大线程数,默认 Integer.MAX_VALUE
queue-capacity: 2147483647 # 队列容量,默认 Integer.MAX_VALUE
keep-alive: 60s # 空闲线程存活时间
allow-core-thread-timeout: true # 是否保持 core-size 数
scheduling: # 任务调度器, job 执行时使用
thread-name-prefix: scheduling- # 线程名前缀,打印日志时使用
pool:
size: 1 # 线程数,默认 1 同时只能运行一个 job 作业
提供一套通用的缓存接口,在某些场景下,比通过 @Cacheable
系列注解的方式更方便的使用缓存。
redis
ehcache
自动注入 com.stark.commons.spring.core.support.cache.CacheService
@Autowired
private CacheService cacheService;
yml
配置spring:
minio:
endpoint: http://192.168.22.100:9000 # 服务器地址,集群需提供一个代理地址
port: 9000 # 端口
secure: false # 是否使用 https 协议
access-key: minio # 用户名
secret-key: 12345678 # 密码
region: china-shandong-1 # 区域
io.minio.MinioClient
并使用。eureka:
server:
enable-registered-event-listener: true # 服务上线(注册)事件监听,默认 true ,以 WARN 级别打印日志
enable-renewed-event-listener: true # 服务续约事件监听,默认 true ,以 INFO 级别打印日志
enable-canceled-event-listener: true # 服务下线监听,默认 true ,以 WARN 级别打印日志
com.stark.commons.spring.web.support.eureka.RegisteredEventHandler
接口,定义上线事件处理器@Component
public class MyRegisteredEventHandler implements RegisteredEventHandler {
@Override
public void handle(EurekaInstanceRegisteredEvent event) {
if (!event.isReplication()) {
// TODO: 业务逻辑
}
}
}
com.stark.commons.spring.web.support.eureka.RenewedEventHandler
接口,定义续约事件处理器@Component
public class MyRenewedEventHandler implements RenewedEventHandler {
@Override
public void handle(EurekaInstanceRenewedEvent event) {
if (!event.isReplication() && event.getInstanceInfo() != null) {
// TODO: 业务逻辑
}
}
}
com.stark.commons.spring.web.support.eureka.CanceledEventHandler
接口,定义下线事件处理器@Component
public class MyCanceledEventHandler implements CanceledEventHandler {
@Override
public void handle(EurekaInstanceCanceledEvent event) {
if (!event.isReplication()) {
// TODO: 业务逻辑
}
}
}
feign:
headers-include: Authorization # 多个以 "," 隔开,将从 request 中复制请求头
feign:
decode-codes:
400: # 为空代表取 exception.message
404: # 为空代表取 exception.message
401: '未登录或登录超时'
403: '没有权限'
499: '客户端关闭连接'
org.springframework.data.domain.Pageable
和 org.springframework.data.domain.Sort
作为接口参数时,不要加 @SpringQueryMap
注解;
自动配置的 com.stark.commons.spring.web.support.page.PageCombinedSerializer
负责 org.springframework.data.domain.Page
的序列化和反序列化。
zuul:
routes:
manager:
service-id: escloud-service-manager
path: /manager/**
route-timeout:
- service-id: escloud-service-manager # 微服务 ID
uri-timeout:
- uri: /user # URI
method: post # 请求方法,默认 get
connect-timeout: 1000 # 连接超时毫秒数,默认 1000
read-timeout: 3000 # 读取数据超时毫秒数,默认 1000
- uri: /user/{id}
method: get
connect-timeout: 1000
read-timeout: 1000
- uri: /user/{id}
method: put
connect-timeout: 1000
read-timeout: 3000
com.stark.commons.spring.web.support.exception.BindExceptionHandler
处理 org.springframework.validation.BindException
异常
com.stark.commons.spring.web.support.exception.ConstraintViolationExceptionHandler
处理 javax.validation.ConstraintViolationException
异常
com.stark.commons.spring.web.support.exception.HttpMessageConversionExceptionHandler
处理 org.springframework.http.converter.HttpMessageConversionException
异常
com.stark.commons.spring.web.support.exception.HttpRequestMethodNotSupportedExceptionHandler
处理 org.springframework.web.HttpRequestMethodNotSupportedException
异常
com.stark.commons.spring.web.support.exception.InvalidGrantExceptionHandler
处理 org.springframework.security.oauth2.common.exceptions.InvalidGrantException
异常
com.stark.commons.spring.web.support.exception.MethodArgumentNotValidExceptionHandler
处理 org.springframework.web.bind.MethodArgumentNotValidException
异常
com.stark.commons.spring.web.support.exception.MethodArgumentTypeMismatchExceptionHandler
处理 org.springframework.web.method.annotation.MethodArgumentTypeMismatchException
异常
com.stark.commons.spring.web.support.exception.ServletRequestBindingExceptionHandler
处理 org.springframework.web.bind.ServletRequestBindingException
异常
注意: 继承内置异常处理器并注入 IOC 容器,可覆盖默认的异常处理器。
com.stark.commons.spring.web.support.exception.ExceptionHandler
接口,处理指定异常,如 KnownException
public class KnownExceptionHandler implements ExceptionHandler {
/**
* 当前异常处理器是否可以处理传入的异常。
* @param ex 异常对象。
* @return 可以处理异常返回 {@literal true} ,否则返回 {@literal false} 。
*/
@Override
public boolean instanceofException(Exception ex) {
return ex instanceof KnownException;
}
/**
* 处理异常并返回响应内容。
* @param ex 异常对象。
* @return 响应内容,包含状态码、异常信息。
*/
@Override
public ResponseEntity<String> handle(Exception ex) {
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(((KnownException) ex).getMessage());
}
}
@Configuration
public class MyConfig {
@Bean
public KnownExceptionHandler knownExceptionHandler() {
return new KnownExceptionHandler();
}
}
com.stark.commons.lang.exception.KnownException
public class UserNotFoundException extends KnownException {
// ...
}
400
状态码和异常信息500
状态码和异常信息yml
配置web:
cors:
enabled: false # 是否允许跨域,默认 false
path-pattern: /** # 允许的请求路径,默认 /**
allowed-origins: '*' # 允许的域名,默认 *
allowed-methods: '*' # 允许的请求方式,默认 *
max-age: 1800 # 允许客户端缓存响应头有效时间,单位秒,默认 1800
yml
配置web:
security-check: true
yml
配置web:
monitor-standard: 3000 # 响应标准时间,单位毫秒
warn
级别打印日志此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。