当前位置: 首页 > 知识库问答 >
问题:

如何在Spring中禁用使用@组件注释创建bean?

顾泰平
2023-03-14

在我的项目中,我有一些重构逻辑的公共接口。看起来是这样的:

public interface RefactorAwareEntryPoint {

    default boolean doRefactor() {
        if (EventLogService.wasEvent(getEventType())) {
            return true;
        }
        boolean result = doRefactorInternal();
        if (result) {
            EventLogService.registerEvent(eventType);
        }
        return result;
    }

    String getEventType();
    
    boolean doRefactorInternal();
}

然后,当我需要编写一些重构时,我用方法实现这个接口,标记类,如组件,Spring-in-loop评估每个接口实现并将其注册到数据库中。但是我们有很多重构(每年有200-300个新的)。很难手动禁用旧的实现,我们在spring上下文中有很多bean。我们可以做些什么吗,例如,使用一些注释-这将在某些条件下禁用组件创建?

例如:

@Component
@Enabled(YEAR.2020)
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

此注释的工作方式如下(伪代码):

if (YEAR.2020) {
  create bean -> new CustomRefactor()
}

什么时候是一年。2021,我们将不再有大豆。2020年,在Spring背景下。

共有3个答案

白星渊
2023-03-14

查看BeanFactoryPostprocessor接口。可能您可以在创建bean之前删除它。

否则,您可以实现自己的BeanFactory,并使用实现创建ApplicationContext。

田宇
2023-03-14

除了我们的同事提供的答案之外,考虑Spring的特性称为“刻板印象注释”。这就是像@Service这样的知名注释在Spring中的定义方式。

一般来说,使用组件注释标记类的事实允许您将类作为spring bean加载,因为被注释的类将成为一个称为“组件扫描”的过程的主体,该过程在启动应用程序上下文时发生。

自spring 4以来,有一个条件接口,基本上可以实现类似于您所说的启用(2020年)的逻辑。

您可以使用内置的“@ConditionalOnProperty”将2020年映射到属性,甚至可以实现自定义条件逻辑。我假设您已经实现了一个自定义条件as@conditionaloneyear

现在,有趣的是(这是我在文章开头提到的“原型”特性),您可以使用自定义的“条件”逻辑创建自己的“组件”注释,并“好像”它是一个常规bean:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@ConditionalOnYear(2020)
@Component
public @interface Year2020OnlyComponent {

    @AliasFor(annotation = Component.class)
    String value() default "";

}
@Year2020OnlyComponent
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

您还可以通过巧妙地使用别名来改进这一点,使注释类似于:

@SinceYearComponent(2020)
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

但这有点超出了这个问题的范围——所以我只是在这里提到一个方向。

当然,即使没有这个“刻板印象”注释特性,也可以按照您的建议仅使用两个注释:

@Component
@SinceYear(2020) // a custom conditional
public class CustomRefactor implements RefactorAwareEntryPoint {
 // Code implementation
}

高恺
2023-03-14

使用注释@Profile,使应用程序配置和bean在某些环境中可用。

您可以在SpringBoot2.4.0参考文档中找到更多信息:3。配置文件

Spring概要文件提供了一种隔离应用程序配置部分的方法,并使其仅在某些环境中可用。任何@组件、@配置或@配置属性都可以标记为@配置文件,以限制其加载时间

将每年视为一个单独的环境。

@Component
@Profile("2020")
public class CustomRefactor2020 implements RefactorAwareEntryPoint {
 // Code implementation
}
@Component
@Profile("2021")
public class CustomRefactor2021 implements RefactorAwareEntryPoint {
 // Code implementation
}
 类似资料:
  • 我试图创建一个使用的组合注释,但是我似乎无法使其工作。 这是有效的(使用): 但是,直接使用不起作用(大概是由于只允许在方法上使用): 无法将用作可组合注释吗?

  • 我想在spring mvc中使用注释方法创建一个示例项目,用户可以通过单击按钮导航到一个页面到另一个页面。我为spring创建了一个新的mvc项目示例 我期待你的帮助先谢谢你 登录。JAVA 登录控制器。JAVA 登录。jsp calc.jsp 所容纳之物jsp 当点击calc页面上的“鼠标”按钮时,会出现以下错误 加上 单击登录页面中的登录按钮时发生以下错误 例外

  • 我正在运行IntelliJ IDEA 2017.3.4(终极版)。我有一个Spring Boot项目,定义了Spring属性,它将自动连接到类中的注释字段中。属性在Application.properties中定义。 如果“My.Property.Value”解析为“TheValue”,将显示如下: 我宁愿它不这样做。是否有禁用此功能的首选项?我没有运气找到答案,搜索的想法,偏好或网上。

  • 我正在使用Spring框架和hazelcast缓存在服务层缓存REST APi。我缓存的api有@Cacheable注释,带有cachename和keygenerator,工作很好。我正在寻找使用application属性或Consuler属性启用/禁用缓存的最佳方法。为此,我试图传递@cachable注释的condition属性中的属性,但没有成功。使用这种方法,我最终将在多个地方传递相同的值(

  • 问题内容: 我试图用来向没有定义主键的表中插入数据。 但是事实是该表的两个字段一起在表中是唯一的。我如何使用hibernate注释实现相同的目的? 这是我的代码。 问题答案: 您可以使用和创建复合键,并将其与您的实体进行映射。例如: 然后在Java代码中使用常规方式来持久化实体。 参考:http : //docs.jboss.org/hibernate/annotations/3.5/refere