SpringBoot是约定优于配置产物,其核心就是所对应的starter,只要在配置文件中填写所需要的参数,就能够实现自动配置。
用阿里云ONS为例,编写一个自定义starter用于发送消息。
开始
新建一个maven模块,增加对应库
<groupId>com.zxcvbnmzsedr</groupId>
<artifactId>ons-module</artifactId>
<version>1.0-SNAPSHOT</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starters</artifactId>
<version>1.3.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-client</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.31</version>
</dependency>
</dependencies>
几个核心类:
- OnsClient: 注解,方法返回值直接发送到阿里云
- OnsClientAspect: 注解的AOP实现
- OnsAutoConfiguration: 整个项目的配置
- OnsProperties: 用于提取配置文件
OnsClient:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface OnsClient {
/**
* 阿里云的topicId
*/
String topicId();
/**
* 指定tags
*/
String tags();
/**
* producerId
*/
String producerId();
}
OnsClientAspect
@Component
@Aspect
public class OnsClientAspect {
private Logger logger = LoggerFactory.getLogger(OnsAutoConfiguration.class);
@Autowired
private Map<String,Producer> onsProducer;
@Pointcut("@annotation(com.zxcvbnmzsedr.ons.annotation.OnsClient)")
private void cut() { }
@Around(value = "cut()&& @annotation(onsClient)")
public Object aroundMethod(ProceedingJoinPoint point, OnsClient onsClient) {
Object result = null;
String producerId = onsClient.producerId();
String tags = onsClient.tags();
Producer producer = onsProducer.get(producerId);
try {
producer.start();
result = point.proceed();
Message message = new Message(onsClient.topicId(),tags, JSON.toJSONBytes(result));
SendResult sendResult = producer.send(message);
assert sendResult != null;
logger.info("messageId"+sendResult.getMessageId());
} catch (ONSClientException e){
logger.error(e.getMessage());
} catch (Throwable e) {
logger.error(e.getMessage());
} finally {
producer.shutdown();
}
return result;
}
}
OnsAutoConfiguration
@Configuration
@EnableConfigurationProperties(OnsProperties.class)
public class OnsAutoConfiguration {
@Autowired
private OnsProperties onsProperties;
@Bean
public Map<String,Producer> onsProducer(){
Map<String,Producer> producerMap = new HashMap<String, Producer>();
for(String producer:onsProperties.getProducerIds()){
ProducerBean producerBean = new ProducerBean();
Properties properties = new Properties();
properties.put(PropertyKeyConst.ProducerId, producer);
properties.put(PropertyKeyConst.AccessKey, onsProperties.getAccessKey());
properties.put(PropertyKeyConst.SecretKey, onsProperties.getAccessKeySecret());
properties.put(PropertyKeyConst.ONSAddr, onsProperties.getOnsAddr());
producerBean.setProperties(properties);
producerMap.put(producer,producerBean);
}
return producerMap;
}
@Bean
public OnsClientAspect onsClientAspect(){
return new OnsClientAspect();
}
}
OnsProperties
@ConfigurationProperties(prefix = "ons")
public class OnsProperties {
private String accessKey;
private String accessKeySecret;
private String onsAddr;
private String[] producerIds;
private String producerId;
@PostConstruct
public void init() {
this.producerIds = producerId.split(",");
}
public String[] getProducerIds() {
return producerIds;
}
public void setProducerIds(String[] producerIds) {
this.producerIds = producerIds;
}
public String getProducerId() {
return producerId;
}
public void setProducerId(String producerId) {
this.producerId = producerId;
}
public String getAccessKey() {
return accessKey;
}
public void setAccessKey(String accessKey) {
this.accessKey = accessKey;
}
public String getAccessKeySecret() {
return accessKeySecret;
}
public void setAccessKeySecret(String accessKeySecret) {
this.accessKeySecret = accessKeySecret;
}
public String getOnsAddr() {
return onsAddr;
}
public void setOnsAddr(String onsAddr) {
this.onsAddr = onsAddr;
}
}
src/main/resources目录下新建META-INF文件夹,然后新建spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.zxcvbnmzsedr.ons.autoconfigure.OnsAutoConfiguration
把这几项配置起来就能使用了
使用方法
在pom文件引用ons模块
<dependency>
<groupId>com.zxcvbnmzsedr</groupId>
<artifactId>ons-module</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
配置文件application.yml
ons:
accessKey: XXX
accessKeySecret: XXX
onsAddr: XXX
# 如果有多个生产者,使用逗号隔开
producerId: XXX,XXX,XXX
在使用时候会把返回值直接序列化成json直接发送到ONS上,
需要指定topicId,producerId,tags
@OnsClient(topicId = "XXX",producerId = "XXX",tags = "XXX")
public String test(){
return "ddd";
}
代码在github上,https://github.com/zxcvbnmzsedr/ons-module