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

a.h*_*.ha 8 spring annotations required

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

这是一个例子.

配置文件中

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

    @Bean
    public MovieHolder holder() {
        return new MovieHolder();
    }
}
Run Code Online (Sandbox Code Playgroud)

MovieHolder.java

public class MovieHolder {

    private Movie movie;

    public Movie getMovie() {
        return movie;
    }

    @Required
    public void setMovie(Movie movie) {
        this.movie = movie;
    }
}
Run Code Online (Sandbox Code Playgroud)

上下文初始化

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MovieHolder holder = (MovieHolder) context.getBean("holder");
System.out.println("movie: " + holder.getMovie());
Run Code Online (Sandbox Code Playgroud)

据我所知,@Required注释的文档,应该会出现异常,因为电影不是直接设置或通过自动装配.而不是输出movie: null.

我究竟做错了什么?或者这不正确使用@Required注释?

Bha*_*ikh 8

在您实例化的bean中设置所需的属性是您自己的责任.在BeanPostProcessor该处理与注解类的豆定义@ConfigurationConfigurationClassPostProcessor.在BeanPostProcessor该处理您的@Required注解默认为RequiredAnnotationBeanPostProcessor,这是在默认情况下,当你使用登记 context:annotation-config,并context:component-scan在您的配置.如果您不使用这两个标签,您甚至可以将自己注册RequiredAnnotationBeanPostProcessorbean.

现在,RequiredAnnotationBeanPostProcessor有一个调用方法的默认实现boolean shouldSkip(..)检查一个名为的布尔属性SKIP_REQUIRED_CHECK_ATTRIBUTE.在后处理过程中,为每个bean检查此属性的值RequiredAnnotationBeanPostProcessor.如果它返回false,@Required则强制执行约束,否则不执行约束.

现在,ConfigurationClassPostProcessor这个属性的值设置为true同时从创建bean定义@Configuration的类(我猜测,如果原因正在定义一个bean,应该确保它具有所需的属性).因此,@Required对这样的bean没有强制执行.

顺便说一句,你可能会认为这个SKIP_REQUIRED_CHECK_ATTRIBUTE属性来自何处以及它在何处设置:它是在BeanDefinitionSpring内部用于bean创建和后处理的实例上设置的.

如果您真的想要强制执行@Required约束,则必须覆盖RequiredAnnotationBeanPostProcessor,覆盖该boolean shouldSkip(..)方法并注册此类而不是默认值RequiredAnnotationBeanPostProcessor.并且正如文档所述RequiredAnnotationBeanPostProcessor:

默认的RequiredAnnotationBeanPostProcessor将由"context:annotation-config"和"context:component-scan"XML标记注册.如果要指定自定义RequiredAnnotationBeanPostProcessor bean定义,请删除或关闭默认注释配置.

另一种方法是initMethod@Bean注释上使用该属性.哪个可以执行检查以确定所需的属性确实已设置.但是,由于这是基于代码的配置,您也可以init自己调用该方法.

另外,在我看来,使用自己的麻烦并没有太大的意义RequiredAnnotationBeanPostProcessor,正如下面的文档所说:

请注意,'init'方法可能仍然需要实现(并且可能仍然需要),因为此类所做的所有操作都强制实际上已经使用值配置了"required"属性.它不会检查任何其他内容...特别是,它不会检查配置的值是否为空.

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