您的位置:首页 > 编程语言 > Java开发

spring-boot-starter包,实现自定义注解开关(如Enablexxx)

2019-09-19 17:58 1406 查看
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 本文链接:https://blog.csdn.net/qq_36382225/article/details/101030722

前提

A项目依赖B项目,B项目配置spring注解,A项目如果直接使用该类,会报错。

  1. 使用@import,一般用于B项目的配置类
  2. 使用本文方式,一般用于无耦合的注解支持

普通注入调用

读取resource/META-INF/spring.factories,如果KEY是org.springframework.boot.autoconfigure.EnableAutoConfiguration,value写需要注入的类,可以加载多个,以逗号分隔。

这是因为在启动类注解@SpringBootApplication

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

追踪@EnableAutoConfiguration后

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

继续追踪@Import(AutoConfigurationImportSelector.class),进入AutoConfigurationImportSelector类

深入跟踪后会发现,项目启动后会去查找spring.factories,并根据上文说的key来注入到spring中,在A项目可以调用B项目注入的类,这个类可以是普通类,也可以是加了@Configuration的配置项类

自定义注解EnableXXX

关键接口org.springframework.context.annotation.ImportSelector;

  1. 自定义注解

    在import中,指定自定义Selector

    重写的方法,返回值作为spring注入的对象,这里需要注入MySerivice
    在A项目依赖B项目后,如果不加@EnableAnn注解,直接注入MyService类,启动报错,加了注解之后启动正常

项目使用

我们使用自定义@enablexxx开启注解支持后,使用AOP针对@businessAnn进行切面操作

  1. 创建自定义注解支持
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(MySelector.class)
public @interface EnableAnn {

}
  1. 创建业务拦截注解
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface BusinessAnn {

}
  1. 创建切面类
@Aspect
@Order(-1) // 保证该AOP在@Transactional之前执行
public class LogAnnotationAspect {

@Around("@annotation(ds)")
public Object logSave(ProceedingJoinPoint joinPoint, BusinessAnn ds) throws Throwable {

Object[] args = joinPoint.getArgs();// 参数值
Object result = joinPoint.proceed();
return result;
}
}
  1. 创建Selector类,并在EnableAnn类中Import
public class MySelector implements ImportSelector{

public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[] {"com.lee.jrlee27_2.config.MyConfig"};
}
}
  1. 创建配置加载类,注入到依赖项目的spring中(如果不加Aspect类注入,AOP不会生效)
@Configuration
public class MyConfig {
@Bean
public LogAnnotationAspect getAspect() {
LogAnnotationAspect l = new LogAnnotationAspect();
return l;
}
}
  1. 主项目引用测试
@RestController
@RefreshScope
@EnableAnn // 开启注解支持
public class Controller extends BaseController {
@RequestMapping("businessAnn")
@BusinessAnn
public void businessAnn() {
System.out.println("businessAnn");
}
}

在加了@BusinessAnn的方法,会进行AOP拦截

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: