spring - @Required 注释如何与 JavaConfig 一起使用?

标签 spring annotations required

我是 Spring 框架的新手,我在理解 @Required 时遇到了问题。注释与 Java 配置的应用程序相结合。

这是一个例子。

配置文件

@Configuration
public class AppConfig {
    @Bean
    public Movie movieA() {
        return new Movie();
    }

    @Bean
    public MovieHolder holder() {
        return new MovieHolder();
    }
}

MovieHolder.java
public class MovieHolder {

    private Movie movie;

    public Movie getMovie() {
        return movie;
    }

    @Required
    public void setMovie(Movie movie) {
        this.movie = movie;
    }
}

上下文初始化
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MovieHolder holder = (MovieHolder) context.getBean("holder");
System.out.println("movie: " + holder.getMovie());

据我了解 @Required 的文档注释,应该有一个异常(exception),因为电影不是直接设置的,也不是通过 Autowiring 的。取而代之的是输出 movie: null .

我究竟做错了什么?或者这不是 @Required 的正确用法吗?注解?

最佳答案

在您正在实例化的 bean 中设置所需的属性是您自己的责任。 BeanPostProcessor 处理用 @Configuration 注释的类中的 bean 定义被称为 ConfigurationClassPostProcessor . BeanPostProcessor 处理您的 @Required注释默认为 RequiredAnnotationBeanPostProcessor , 使用 context:annotation-config 时默认注册和 context:component-scan在您的配置中。如果你没有使用这两个标签,你甚至可以注册自己的 RequiredAnnotationBeanPostProcessor 作为 bean .

现在, RequiredAnnotationBeanPostProcessor 的默认实现有一个方法叫 boolean shouldSkip(..)检查名为 SKIP_REQUIRED_CHECK_ATTRIBUTE 的 bool 属性. RequiredAnnotationBeanPostProcessor 在后处理期间为每个 bean 检查此属性的值。 .如果返回 false , @Required强制执行约束,否则不执行。

现在, ConfigurationClassPostProcessor 将此属性的值设置为 true@Configuration 创建 bean 定义时类(我猜是因为如果你定义一个 bean,你应该确保它具有所需的属性)。因此,@Required不对此类 bean 强制执行。

顺便说一句,您可能会认为这是在哪里做的 SKIP_REQUIRED_CHECK_ATTRIBUTE 属性来自哪里以及它在哪里设置:它设置在 BeanDefinition 的实例上Spring 在内部使用它们来创建 bean 和进行后处理。

如果你真的想强制执行 @Required约束,您必须覆盖 RequiredAnnotationBeanPostProcessor ,覆盖 boolean shouldSkip(..)方法并注册这个类而不是默认的 RequiredAnnotationBeanPostProcessor .而作为 RequiredAnnotationBeanPostProcessor 的文档说:

A default RequiredAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags. Remove or turn off the default annotation configuration there if you intend to specify a custom RequiredAnnotationBeanPostProcessor bean definition.



另一种方法是使用 initMethod您的 @Bean 上的属性注解。哪个可以执行检查以查看确实设置了所需的属性。但是,由于这是基于代码的配置,您也可以将其称为 init自己方法。

另外,在我看来,使用自己的 RequiredAnnotationBeanPostProcessor 经历很多麻烦没有多大意义。 ,如以下文档所述:

Please note that an 'init' method may still need to implemented (and may still be desirable), because all that this class does is enforce that a 'required' property has actually been configured with a value. It does not check anything else... In particular, it does not check that a configured value is not null.



所以,总结一下: @Required不适用于 @Configuration默认的类。如果您需要确保设置所有属性,您也可以在 @Bean 中创建 bean 时自己完成。方法(通过调用一些执行此类验证的 init 方法,或者只是自己提供所需的属性)。如果你真的需要制作 @Required注释工作,您需要使用自己的 RequiredAnnotationBeanPostProcessor 实现,在spring上下文中注册为bean,放弃context:annotation-config的好处.

关于spring - @Required 注释如何与 JavaConfig 一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16769360/

相关文章:

r - 在 facet_wrap 标签上显示注释

Excel VBA - WorksheetFunction.CountA 错误 - 需要对象

HTML5 &lt;input&gt; 必需属性但不在 <form> 内

java - 如何在 Spring Boot 中为所有 Controller 指定前缀?

java - Spring,无法在测试中加载ApplicationContext

java - Spring Boot + Elastic Search +排除类字段

Oracle Apex 5.1 - 如何根据特定条件在文本字段上动态显示/隐藏 '*' 必需符号

mysql - Spring Data REST持久化MySQL一对多内嵌对象更新(PUT/PATCH)

java - AspectJ 切入点模式,用于调用具有特定注释的类成员上的方法

java - AspectJ - 指定方法的切入点,其参数用类级别注释进行注释