我正在使用SpringBoot的@Value注释从默认的application.properties文件填充对象属性,但是在Filter覆盖中看到了一些奇怪的行为。

我的调试器中有两个断点:

@Component
  public class BasicFilter implements Filter {

  @Value("${aad.client_id}")
  private String clientId;

  @Bean
  public FilterRegistrationBean registerFilter() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(new BasicFilter()); // <-- 1.
    registration.addUrlPatterns("/secure/*");
    return registration;
  }

  public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException {
    if (request instanceof HttpServletRequest) { // <- 2.
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        ...

在1 .: this.client_id设置为'foo'(来自application.properties
A2 2.:this.client_id为空

对不同/缺失值有任何解释吗?

最佳答案

您正在将new BasicFilter()注入(inject)FilterRegistrationBean。在这种情况下,您正在创建一个新对象,但它不是Spring托管的bean,因此其clientId将为空。所以基本上您现在有2个实例:

  • 一个由Spring创建的,由于@Component批注
  • 使用FilterRegistrationBean关键字(不是由Spring管理)注入(inject)new中的一个

  • 您可能应该将registerFilter()方法移动到一个单独的配置类(用@Configuration)注释,然后将BasicFilter bean Autowiring /注入(inject)到该方法中,例如:
    @Configuration
    public class FilterConfig {
        @Bean
        public FilterRegistrationBean registerFilter(BasicFilter filter) { // Inject it
            FilterRegistrationBean registration = new FilterRegistrationBean();
            registration.setFilter(filter); // Use it
            registration.addUrlPatterns("/secure/*");
            return registration;
       }
    }
    

    可选地,如果要将@Bean方法保留在过滤器本身中,则应将其替换为this,因为当前对象是由Spring管理的,而新实例将不是:
    @Bean
    public FilterRegistrationBean registerFilter() {
        FilterRegistrationBean registration = new FilterRegistrationBean();
        registration.setFilter(this);
        registration.addUrlPatterns("/secure/*");
        return registration;
    }
    

    相关:Spring @Value annotation always evaluating as null?

    10-07 19:17
    查看更多