java - 如何判断ApplicationConfig.class是否带有自定义注解

标签 java spring spring-mvc annotations spring-boot

我想根据标记 ApplicationConfig.class 的自定义注释的存在来启用应用程序功能,如下所示:

@FooBar(enabled = true)
@Configuration
@ComponentScan(basePackageClasses = Application.class, excludeFilters = @Filter({Controller.class, Configuration.class}))
@EnableJpaRepositories("com.package.repository")
class ApplicationConfig { 
    // Application specific configs and bean defs.
}

自定义注释名为FooBar:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface FooBar   {
    boolean enabled() default true;
}

在应用程序启动期间,我想检测该类(或任何其他类/bean)是否使用此注释进行注释。

这是我的尝试,部分基于此 similar question它包括两种方法来确定注释正在被使用。

@Component
public class MyClassWithEventListeners implements ApplicationContextAware {

@Autowired
ApplicationEventPublisher applicationEventPublisher;

@Autowired
ApplicationContext applicationContext;


@EventListener
void contextRefreshedEvent(ContextRefreshedEvent event) {
    ApplicationContext applicationContext = event.getApplicationContext();
    applicationContext.getClassLoader();

    AutowireCapableBeanFactory autowireCapableBeanFactory = applicationContext.getAutowireCapableBeanFactory();

    String[] names = event.getApplicationContext().getBeanDefinitionNames();

    for (String name : names) {
        Object o = autowireCapableBeanFactory.getBean(name);
        if (AopProxyUtils.ultimateTargetClass(o).isAnnotationPresent(FooBar.class)) {
            System.out.println("Found class annotated with FooBar");
        }
    }

}

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    this.applicationContext = applicationContext;
    List<String> beanNames = getBeansWithAnnotation(FooBar.class);
    if(beanNames !=null){
        System.out.println("Found class annotated with FooBar");
    }
}

public List<String> getBeansWithAnnotation(Class<? extends Annotation> type) {
    Predicate<Map<String, Object>> filter = Predicates.alwaysTrue();
    return getBeansWithAnnotation(type, filter);
}

public List<String> getBeansWithAnnotation(Class<? extends Annotation> type, Predicate<Map<String, Object>> attributeFilter) {

    List<String> result = Lists.newArrayList();

    ConfigurableListableBeanFactory factory = ((ConfigurableApplicationContext) applicationContext).getBeanFactory();
    for (String name : factory.getBeanDefinitionNames()) {
        BeanDefinition bd = factory.getBeanDefinition(name);

        if (bd.getSource() instanceof StandardMethodMetadata) {
            StandardMethodMetadata metadata = (StandardMethodMetadata) bd.getSource();

            Map<String, Object> attributes = metadata.getAnnotationAttributes(type.getName());
            if (null == attributes) {
                continue;
            }

            if (attributeFilter.apply(attributes)) {
                result.add(name);
            }
        }
    }

    return result;
}
}

contextRefreshedEvent()setApplicationContext() 方法均被调用,但都无法检测到自定义注释。

我观察到我的 ApplicationConfig.class 出现在 beans/classes 列表中,但显示如下:

com.package.config.ApplicationConfig$$EnhancerBySpringCGLIB$$15073fb3@196887

  • 这是什么EnhancedBySpring
  • Spring 如何添加功能? @EnableJpaRepositories 添加存储库。我想出于自己的目的复制此功能。

最佳答案

核心容器实际上支持这些内容,因此无需破解上下文。您可能会受益于阅读在配置类上添加 @EnableXYZ 时发生的情况。例如 @EnableCaching@EnableJms 的工作方式几乎相同:

该接口(interface)使用@Import进行元注释,这会导致上下文加载更多bean。在我看来,enabled 部分有点无用。注释的存在或不存在起着相同的作用,并且更加明确。

关于java - 如何判断ApplicationConfig.class是否带有自定义注解,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34827256/

相关文章:

java - Thymeleaf 模板中的迭代不起作用

java - 通过 WebSocketServlet 配置的 Jetty WebSockets over HTTPS

java - 无法通过 Twitter 应用程序中的 postman 注册 Webhook

java - Android 在单击时更改 TextView 中的文本大小

java - spring中的实例变量在多线程环境中导致问题

java - 在 Spring 中用另一个 Controller 重置 Controller

java - 如何在 JSP 中显示数据库中的图像?

java - 使用 datastax 对象映射器映射列表/集/映射类型的列

java - Spring Datasource事务管理器问题

java - 事务无回滚 - Spring Boot 2.0