SpringBoot是约定优于配置产物,其核心就是所对应的starter,只要在配置文件中填写所需要的参数,就能够实现自动配置。
用阿里云ONS为例,编写一个自定义starter用于发送消息。
开始
新建一个maven模块,增加对应库
1 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
| <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:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OnsClient {
String topicId();
String tags();
String producerId(); }
|
OnsClientAspect
1 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
| @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
1 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
| @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
1 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
| @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文件
1 2
| org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.zxcvbnmzsedr.ons.autoconfigure.OnsAutoConfiguration
|
把这几项配置起来就能使用了
使用方法
在pom文件引用ons模块
1 2 3 4 5
| <dependency> <groupId>com.zxcvbnmzsedr</groupId> <artifactId>ons-module</artifactId> <version>1.0-SNAPSHOT</version> </dependency>
|
配置文件application.yml
1 2 3 4 5 6
| ons: accessKey: XXX accessKeySecret: XXX onsAddr: XXX producerId: XXX,XXX,XXX
|
在使用时候会把返回值直接序列化成json直接发送到ONS上,
需要指定topicId,producerId,tags
1 2 3 4 5
| @OnsClient(topicId = "XXX",producerId = "XXX",tags = "XXX") public String test(){
return "ddd"; }
|
代码在github上,https://github.com/zxcvbnmzsedr/ons-module