spring boot中通过开发jar包,检查目标应用的注解的非法使用

背景

在spring boot工程中,@FeignClient和@RequestMapping可能被错误得加到同一个方法上,当用户这么使用的情况下,如何能够在程序启动的过程中警告用户并抛出异常呢?本文将给出这个问题的解决方法。

思路

  1. 通过提供一个jar包,任何引入该jar包的应用在启动过程中自动执行注解使用检查
  2. jar包需要添加一个Listener,监听应用启动的过程,执行检查工作

步骤

  1. 实现注解检查Listener
  2. 启动spring boot自动配置
  3. 目标应用启动@EnableAutoCongiguration自动配置

代码

Listener定义
@Component
@ConditionalOnClass(FeignClient.class)
public class AnnotationCheckListener implements ApplicationListener<ContextRefreshedEvent> {
  @Autowired
  public ApplicationContext applicationContext;

  @Override
  public void onApplicationEvent(ContextRefreshedEvent event) {

    String[] beanNamesForAnnotation = applicationContext.getBeanNamesForAnnotation(RequestMapping.class);

    Arrays.stream(beanNamesForAnnotation)
        .filter(beanName -> applicationContext.findAnnotationOnBean(beanName, FeignClient.class) != null)
        .forEach(beanName -> throwAnnotationConfigurationException(beanName));
  }

  static void throwAnnotationConfigurationException(String beanName) {
    throw new AnnotationConfigurationException("Cannot have both @RequestMapping and @FeignClient on " + beanName);
  }
}
配置spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.swagger.starter.AnnotationCheckListener

总结

  1. SpringFactoriesLoader
    SpringFactoriesLoader
     loads and instantiates factories of a given type from "META-INF/spring.factories" files which may be present in multiple JAR files in the classpath. The spring.factories file must be in Properties format, where the key is the fully qualified name of the interface or abstract class, and the value is a comma-separated list of implementation class names.
  2. @EnableAutoCongiguration Spring Boot提供的@EnableAutoCongiguration功能很强大,所有的配置似乎都被包含进来而无需开发者显式声明。EnableAutoConfigurationImportSelector使用的是spring-core模块中的SpringFactoriesLoader#loadFactoryNames()方法,它的作用是在类路径上扫描并加载META-INF/spring.factories文件中定义的类。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import({ EnableAutoConfigurationImportSelector.class,
        AutoConfigurationPackages.Registrar.class })
public @interface EnableAutoConfiguration {

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     */
    Class<?>[] exclude() default {};

}

备选

@Component
@ConditionalOnClass(FeignClient.class)
@Slf4j
public class FeignClientBeanProcessor implements BeanPostProcessor{
  @Override
  public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
    return null;
  }

  @Override
  public Object postProcessAfterInitialization(Object bean, String s) throws BeansException {
    final Class<?> beanClass = bean.getClass();
    if(beanClass.isAnnotationPresent(RequestMapping.class) && beanClass.isAnnotationPresent(FeignClient.class)) {
      log.error("RequestMapping and FeignClient annotation could not be added to the same class.");
      return new BeanCreationException("RequestMapping and FeignClient annotation could not be added to the same " +
          "class");
    }
    return null;
  }
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值