仅需四步,写一个springboot starter

这个系列分为5篇

1. @Component,@Service等注解是如何被解析的

2. @Enable驱动原理

3. @EnableAutoConfiguration处理逻辑

4. spring,springBoot事件

5.仅需四步,写一个springboot starter

引言

只要你用Springboot,一定会用到各种spring-boot-starter。其实写一个spring-boot-starter

,仅需4步。下面我们就写一个starter,它将实现,在日志中打印方法执行时间。


第一步 创建maven项目

在使用spring-boot-starter,会发现,有的项目名称是 XX-spring-boot-starter,有的是

spring-boot-starter-XX,这个项目的名称有什么讲究呢?

从springboot官方文档摘录如下:

Do not start your module names with spring-boot, even if you use a different Maven groupId. We may offer official support for the thing you auto-configure in the future.

As a rule of thumb, you should name a combined module after the starter.

从这段话可以看出spring-boot-starter命名的潜规则。

命名潜规则

spring-boot-starter-XX是springboot官方的starter

XX-spring-boot-starter是第三方扩展的starter

打印方法执行时间的功能,需要用到aop,咱们的项目就叫做

aspectlog-spring-boot-starter吧。

项目的pom文件如下:

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">

<modelVersion>4.0.0</modelVersion>

<groupId>org.example</groupId>

<artifactId>aspectlog-spring-boot-starter</artifactId>

<version>1.0.2</version>

<parent>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>2.1.15.RELEASE</version>

</parent>

<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-autoconfigure</artifactId>

</dependency>

<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>

</dependencies>

</project>

关于spring-boot-configuration-processor的说明,引自springBoot官方文档:


Spring Boot uses an annotation processor to collect the conditions on auto-configurations in a metadata file ( META-INF/spring-autoconfigure-metadata.properties ). If that file is present, it is used to eagerly filter auto-configurations that do not match, which will improve startup time. It is recommended to add the following dependency in a module that contains auto-configurations:

<dependency>

<groupId> org.springframework.boot </groupId>

<artifactId> spring-boot-autoconfigure-processor </artifactId>

<optional> true </optional>

</dependency>


简单说就是 写starter时,在pom中配置spring-boot-autoconfigure-processor,

在编译时会自动收集配置类的条件,写到一个META-INF/spring-autoconfigure-metadata.properties中。


第二步写自动配置逻辑

各种condition


类型注解说明

Class Conditions

类条件注解

@ConditionalOnClass

当前classpath下

有指定类才加载

@ConditionalOnMissingClass

当前classpath下

无指定类才加载

Bean Conditions

Bean条件注解

@ConditionalOnBean

当期容器内有

指定bean才加载

@ConditionalOnMissingBean

当期容器内无

指定bean才加载

Property Conditions

环境变量条件

注解(含配置文件)

@ConditionalOnProperty

prefix 前缀

name 名称

havingValue

用于匹配配置项值

matchIfMissing

没找指定配置项时

的默认值

Resource

Conditions

资源条件注解

@ConditionalOnResource有指定资源才加载

Web Application Conditions

web条件注解

@ConditionalOnWebApplication是web才加载
@ConditionalOnNotWebApplication不是web才加载
SpEL Expression Conditions@ConditionalOnExpression符合SpEL 表达式才加载

本次我们就选用@ConditionalOnProperty。即配置文件中有aspectLog.enable=true,才加载我们的配置类。

下面开始写自动配置类


2.1.定义AspectLog注解,该注解用于标注需要打印执行时间的方法。

package com.shanyuan.autoconfiguration.aspectlog;

import java.lang.annotation.ElementType;

import java.lang.annotation.Retention;

import java.lang.annotation.RetentionPolicy;

import java.lang.annotation.Target;

/**

* class_name: ScheduleManage

* describe: 用于控制定时任务的开启与关闭

* 对应切面

* creat_user: wenl

* creat_time: 2018/11/10 18:45

**/

@Target(ElementType.METHOD)

@Retention(RetentionPolicy.RUNTIME)

public @interface AspectLog {

}

2.2定义配置文件对应类

package com.shanyuan.autoconfiguration.aspectlog;

import org.springframework.boot.context.properties.ConfigurationProperties;

@ConfigurationProperties("aspectLog")

public class AspectLogProperties {

private boolean enable;

public boolean isEnable() {

returnenable;

}

public void setEnable(boolean enable) {

this.enable = enable;

}

}

2.3定义自动配置类


package com.shanyuan.autoconfiguration.aspectlog;

import org.aspectj.lang.ProceedingJoinPoint;

import org.aspectj.lang.annotation.Around;

import org.aspectj.lang.annotation.Aspect;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.boot.autoconfigure.condition.*;

import org.springframework.context.annotation.Configuration;

import org.springframework.context.annotation.EnableAspectJAutoProxy;

import org.springframework.core.PriorityOrdered;

@Aspect

@EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)

@Configuration

@ConditionalOnProperty(prefix = "aspectLog", name = "enable",

havingValue = "true", matchIfMissing = true)

public class AspectLogAutoConfiguration implements PriorityOrdered {

protected Logger logger = LoggerFactory.getLogger(getClass());

@Around("@annotation(com.shanyuan.autoconfiguration.aspectlog.AspectLog) ")

public Object isOpen(ProceedingJoinPoint thisJoinPoint)

throws Throwable {

//执行方法名称

String taskName = thisJoinPoint.getSignature()

.toString().substring(

thisJoinPoint.getSignature()

.toString().indexOf(" "),

thisJoinPoint.getSignature().toString().indexOf("("));

taskName = taskName.trim();

long time = System.currentTimeMillis();

Object result = thisJoinPoint.proceed();

logger.info("method:{} run :{} ms", taskName,

(System.currentTimeMillis() - time));

return result;

}

@Override

public int getOrder() {

//保证事务等切面先执行

return Integer.MAX_VALUE;

}

}

配置类简要说明:

@ConditionalOnProperty(prefix = "aspectLog", name = "enable",havingValue = "true", matchIfMissing = true)

当配置文件有aspectLog.enable=true时开启,如果配置文件没有设置aspectLog.enable也开启。


第三步META-INF/spring.factories

META-INF/spring.factories是spring的工厂机制,在这个文件中定义的类,都会被自动加载。多个配置使用逗号分割,换行用\

如果有兴趣可以查看这2篇blog:

2.@Enable驱动原理(设置连接)

3.@EnableAutoConfiguration处理逻辑(设置连接)

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\

com.shanyuan.autoconfiguration.aspectlog.AspectLogAutoConfiguration

第四步打包测试

这是我们最终的目录结构

在IDEA中,进行mvn intall


打包完成后,在其他项目中的pom中引入进行测试


参考资料

https://docs.spring.io/spring-boot/docs/2.1.15.RELEASE/reference/html/boot-features-developing-auto-configuration.html#boot-features-custom-starter





以上是 仅需四步,写一个springboot starter 的全部内容, 来源链接: utcz.com/a/35352.html

回到顶部