【Spring】手写一个简易starter
需求:
? ? ? ? 自定义一个starter,里面包含一个@TimeLog注解和一个TimeLogAspect切面类,用于统计接口耗时。要求在其它项目引入starter依赖后,启动springboot项目时能进行自动装配。
步骤:
? ? ? ? (1)引入pom依赖:
<dependencies>
<!-- starter想要有自动装配功能,就需要引入该依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
<!-- aop相关依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
? ? ? ? (2)定义注解@TimeLog:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TimeLog {
}
? ? ? ? @Target:注解作用“对象”,这里声明注解作用在方法上。
? ? ? ? @Retention:表示注解在运行时会被保留,可以通过反射机制读取。
? ? ? ? (3)定义切面类TimeLogAspect:
@Aspect
@Component
public class TimeLogAspect {
//切点:所有标注了TimeLog注解的方法
@Pointcut("@annotation(com.hammajang.annotation.TimeLog)")
public void timeConsume(){
}
@Around("timeConsume()")
public Object doAround(ProceedingJoinPoint proceedingJoinPoint) {
//开始时间
long start = System.currentTimeMillis();
Object result = null;
try {
//proceedingJoinPoint.proceed():真正的业务处理逻辑
//result:业务的返回结果
result = proceedingJoinPoint.proceed();
} catch (Throwable e) {
e.printStackTrace();
}
//结束时间
long end = System.currentTimeMillis();
System.out.println(proceedingJoinPoint.getSignature().getName() + "接口执行总耗时:" + (end - start) +"ms");
return result;
}
}
? ? ? ? @Aspect:声明这是一个切面类。
? ? ? ? @Component:声明这是一个bean,在项目启动时需要加载到Spring容器中。
? ? ? ? (4)定义TimeLogProperties:
@ConfigurationProperties(prefix = "hammajang")
@Data
public class TimeLogProperties {
/**
* 日志开关
*/
private boolean enable;
}
? ? ? ? @ConfigurationProperties:将配置文件中的属性绑定到 JavaBean(TimeLogProperties)中。注解声明了前缀是hammajang,获取以hammajang为前缀的所有参数进行自动匹配,赋值给类中对应的字段。
? ? ? ? (5)定义TimeLogAutoConfiguration:
@Configuration
@ComponentScan(basePackages = "com.hammajang")
@ConditionalOnProperty(prefix = "hammajang",name = "enable",havingValue = "true")
@EnableConfigurationProperties(value = TimeLogProperties.class)
public class TimeLogAutoConfiguration {
}
? ? ? ? @Configuration:声明这是一个配置类(会被配置成bean,装载到spring容器中)。
? ? ? ? @ComponentScan:扫描指定包路径(可以指定多个),将路径下符合要求的类对象配置成bean,装载到spring容器中。
? ? ? ? @ConditionalOnproperty:表示配置文件中存在一个以"hammajang"为前缀的属性,属性名为"enable",当enable的值为true时(havingValue = "true"),才会将TimeLogAutoConfiguration配置类装载到spring容器中。
? ? ? ? @EnableConfigurationProperties:启用指定配置类,value属性是一个class数组,表示可以启用多个配置类。
? ? ? ? (6)编译、打包starter:
测试starter:
? ? ? ? (1)在pom文件中引入我们自定义的starter:
<dependency>
<groupId>com.hammajang</groupId>
<artifactId>my-spring-boot-starter</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
? ? ? ? (2)在controller层编写测试接口:
@RestController
@RequestMapping("/order")
public class OrderController {
@GetMapping("/test")
@TimeLog
public String test(){
try {
System.out.println("测试TimeLog注解...");
//模拟业务处理
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "success";
}
}
? ? ? ? (3)测试@TimeLog注解是否生效:
? ? ? ? 测试结果:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!