简单介绍
Spring Starter 自定义思路本质上是把实现功能实例对象变成Spring Bean,放到Spring IoC容器。里面所谓的约定大于配置,是指我这个Bean的实现依赖于配置,如果用户没有配置这个,则使用默认的配置。 非官方 starter 命名应遵循 {name}-spring-boot-starter 的格式。
手写一个没有配置项的Starter
这里写一个数据库事物为例
第一步: 引入maven依赖。把starter解析逻辑放置进去
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<scope>provided</scope>
</dependency>
第二步: 编写核心功能Java对象,这里只管逻辑实现,不考虑和Spring IoC无关
java
@Slf4j
public class DefaultYnTransactionManager implements YnTransactionManager {
@Setter
private DataSourceTransactionManager transactionManager;
public final static DefaultYnTransactionManager build(org.springframework.jdbc.datasource.DataSourceTransactionManager manager) {
DefaultYnTransactionManager obj = new DefaultYnTransactionManager();
obj.setTransactionManager(manager);
return obj;
}
@Override
public <T> T execute(Supplier<T> supplier) {
T result = null;
TransactionStatus transaction = null;
try {
transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
result = supplier.get();
transactionManager.commit(transaction);
} catch (BusinessException e) {
log.warn("DefaultYnTransactionManager[]execute BusinessException fail",e);
transactionManager.rollback(transaction);
} catch (Throwable e) {
log.error("DefaultYnTransactionManager[]execute Throwable fail",e);
transactionManager.rollback(transaction);
}
return result;
}
@Override
public void submit(Function0 function0) {
TransactionStatus transaction = null;
try {
transaction = transactionManager.getTransaction(new DefaultTransactionDefinition());
function0.exec();
transactionManager.commit(transaction);
} catch (BusinessException e) {
log.warn("DefaultYnTransactionManager[]execute BusinessException fail",e);
transactionManager.rollback(transaction);
} catch (Throwable e) {
log.error("DefaultYnTransactionManager[]execute Throwable fail",e);
transactionManager.rollback(transaction);
}
}
}
第三步: 自动配置,生成SpringBean 注入到IoC中
- 自动配置类
java
@Configuration
@ConditionalOnMissingBean(value = YnTransactionManager.class)
public class YnTransactionManagerAutoConfiguration {
@Bean
@ConditionalOnBean(value = org.springframework.jdbc.datasource.DataSourceTransactionManager.class)
public YnTransactionManager ynTransactionManager(org.springframework.jdbc.datasource.DataSourceTransactionManager
transactionManager) {
return DefaultYnTransactionManager.build(transactionManager);
}
}
- @Configuration 声明这个类配置类
- @Bean 在方法上声明一个bean
- @ConditionalOnXX 系列,只有当条件满足时候才会生成bean
- 在resource/META-INF/spring.factoris添加,Spring 可以解析这个配置
properties
org.springframework.boot.autoconfigure.EnableAutoConfiguration =\
com.xxx.yn.framework.core.transaction.YnTransactionManagerAutoConfiguration,\
- ok,后面就可以映入依赖去使用了
有配置项
这里已自定义线程池为例
- 第一步: 引入Maven依赖,同上
第二步: 编写核心功能Java对象,这里只管逻辑实现,不考虑是否注入到springIOC中。但是这里要考虑用户可以自定的配置
java
@Data
@ConfigurationProperties(prefix = "yn.thread")
public class ThreadPoolProperties {
/**
* 核心线程数量
*/
private Integer corePoolSize = 2 * Runtime.getRuntime().availableProcessors();
/**
* 最大线程数量
*/
private Integer maxPoolSize = 3 * Runtime.getRuntime().availableProcessors();
/**
* 线程保持时间,一般是任务的执行时间 加点buffer,单位秒
*/
private Long keepAliveTimeForSeconds = 10L;
}
第三步: 自动配置,生成SpringBean
- 配置类
java
@Configuration
@EnableConfigurationProperties({ThreadPoolProperties.class})
public class ThreadPoolAutoConfiguration {
@Bean
@ConditionalOnMissingBean({ThreadPoolExecutor.class})
public ThreadPoolExecutor threadPoolExecutor(ThreadPoolProperties properties) {
ThreadPoolExecutor threadPoolExecutor
= new ThreadPoolExecutor(properties.getCorePoolSize(),
properties.getMaxPoolSize(),
properties.getKeepAliveTimeForSeconds(),
TimeUnit.SECONDS,
new LinkedBlockingQueue<>()
);
threadPoolExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
return threadPoolExecutor;
}
}
- @EnableConfigurationProperties 启动属性配置类也变成一个bean注入到IoC中,在不同的starter中可以同时使用,不会冲突
2.在resource/META-INF/spring.factoris添加
properties
org.springframework.boot.autoconfigure.EnableAutoConfiguration =\
com.gitub.yn.framework.core.thread.ThreadPoolAutoConfiguration,\
- 引入java包就可以生效了