SpringBoot SpringBoot Starter
下面定义一个starter,它将实现,在日志中打印方法执行时间。

1、创建Maven项目

项目命名规则

:::info spring-boot-starter-XX是springboot官方的starter
XX-spring-boot-starter是第三方扩展的starter :::

项目的pom依赖文件

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <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">
  3. <modelVersion>4.0.0</modelVersion>
  4. <groupId>com.fcant</groupId>
  5. <artifactId>aspectlog-spring-boot-starter</artifactId>
  6. <version>1.0.2</version>
  7. <parent>
  8. <groupId>org.springframework.boot</groupId>
  9. <artifactId>spring-boot-starter-parent</artifactId>
  10. <version>2.1.15.RELEASE</version>
  11. </parent>
  12. <dependencies>
  13. <dependency>
  14. <groupId>org.springframework.boot</groupId>
  15. <artifactId>spring-boot-autoconfigure</artifactId>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.boot</groupId>
  19. <artifactId>spring-boot-starter-aop</artifactId>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.springframework.boot</groupId>
  23. <artifactId>spring-boot-configuration-processor</artifactId>
  24. <optional>true</optional>
  25. </dependency>
  26. </dependencies>
  27. </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:

  1. <dependency>
  2. <groupId>org.springframework.boot</groupId>
  3. <artifactId>spring-boot-autoconfigure-processor</artifactId>
  4. <optional>true</optional>
  5. </dependency>

简单说就是 写starter时,在pom中配置spring-boot-autoconfigure-processor, 在编译时会自动收集配置类的条件,写到一个META-INF/spring-autoconfigure-metadata.properties中

2、写自动配置逻辑

各种condition

类型 注解 说明
Class Conditions类条件注解 @ConditionalOnClass 当前classpath下有指定类才加载

@ConditionalOnMissingClass 当前classpath下无指定类才加载
Bean ConditionsBean条件注解 @ConditionalOnBean 当期容器内有指定bean才加载
@ConditionalOnMissingBean 当期容器内无指定bean才加载
Property Conditions环境变量条件注解(含配置文件) @ConditionalOnProperty prefix 前缀name 名称havingValue 用于匹配配置项值matchIfMissing 没找指定配置项时的默认值
ResourceConditions 资源条件注解 @ConditionalOnResource 有指定资源才加载
Web Application Conditionsweb条件注解 @ConditionalOnWebApplication 是web才加载
@ConditionalOnNotWebApplication 不是web才加载
SpEL Expression Conditions @ConditionalOnExpression 符合SpEL 表达式才加载

选用 @ConditionalOnProperty 。即配置文件中有 aspectLog.enable=true ,才加载我们的配置类。下面开始写自动配置类

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

  1. import java.lang.annotation.ElementType;
  2. import java.lang.annotation.Retention;
  3. import java.lang.annotation.RetentionPolicy;
  4. import java.lang.annotation.Target;
  5. /**
  6. * class_name: ScheduleManage
  7. * describe: 用于控制定时任务的开启与关闭
  8. * 对应切面
  9. **/
  10. @Target(ElementType.METHOD)@ Retention(RetentionPolicy.RUNTIME)
  11. public@ interface AspectLog {}

2.2定义配置文件对应类

  1. import org.springframework.boot.context.properties.ConfigurationProperties;@
  2. ConfigurationProperties("aspectLog")
  3. public class AspectLogProperties {
  4. private boolean enable;
  5. public boolean isEnable() {
  6. return enable;
  7. }
  8. public void setEnable(boolean enable) {
  9. this.enable = enable;
  10. }
  11. }

2.3定义自动配置类

  1. import org.aspectj.lang.ProceedingJoinPoint;
  2. import org.aspectj.lang.annotation.Around;
  3. import org.aspectj.lang.annotation.Aspect;
  4. import org.slf4j.Logger;
  5. import org.slf4j.LoggerFactory;
  6. import org.springframework.boot.autoconfigure.condition.*;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.EnableAspectJAutoProxy;
  9. import org.springframework.core.PriorityOrdered;
  10. @Aspect
  11. @EnableAspectJAutoProxy(exposeProxy = true, proxyTargetClass = true)
  12. @Configuration
  13. @ConditionalOnProperty(prefix = "aspectLog", name = "enable",
  14. havingValue = "true", matchIfMissing = true)
  15. public class AspectLogAutoConfiguration implements PriorityOrdered {
  16. protected Logger logger = LoggerFactory.getLogger(getClass());
  17. @Around("@annotation(com.fcant.autoconfiguration.aspectlog.AspectLog) ")
  18. public Object isOpen(ProceedingJoinPoint thisJoinPoint)
  19. throws Throwable {
  20. //执行方法名称
  21. String taskName = thisJoinPoint.getSignature()
  22. .toString().substring(
  23. thisJoinPoint.getSignature()
  24. .toString().indexOf(" "),
  25. thisJoinPoint.getSignature().toString().indexOf("("));
  26. taskName = taskName.trim();
  27. long time = System.currentTimeMillis();
  28. Object result = thisJoinPoint.proceed();
  29. logger.info("method:{} run :{} ms", taskName,
  30. (System.currentTimeMillis() - time));
  31. return result;
  32. }
  33. @Override
  34. public int getOrder() {
  35. //保证事务等切面先执行
  36. return Integer.MAX_VALUE;
  37. }
  38. }

配置类简要说明:
@ConditionalOnProperty(prefix = "aspectLog", name = "enable",havingValue = "true", matchIfMissing = true)
当配置文件有 aspectLog.enable=true 时开启,如果配置文件没有设置aspectLog.enable也开启。

3、META-INF/spring.factories

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

  1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  2. com.fcant.autoconfiguration.aspectlog.AspectLogAutoConfiguration

4、执行打包测试

使用 mvn intall 命令对工程进行打包

  1. mvn intall

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