5

I'm using SpringBoot's @Value annotation to populate an object property from the default application.properties file, but seeing some strange behaviour in a Filter override.

There are two breakpoints in my debugger:

@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;
        ...

At 1.: this.client_id is set to 'foo' (from application.properties A2 2.: this.client_id is null

Any explanation for the different/missing values?

1
  • 1
    show us your properties file entry where it is declared Commented Dec 11, 2017 at 9:17

1 Answer 1

8

You're injecting a new BasicFilter() into the FilterRegistrationBean. In this case, you're creating a new object, but it won't be a Spring managed bean, so its clientId will be empty. So basically you have 2 instances now:

  1. One created by Spring due to the @Component annotation
  2. One injected into the FilterRegistrationBean using the new keyword (not managed by Spring)

You should likely move the registerFilter() method to a separate configuration class (annotated with @Configuration) and autowire/inject the BasicFilter bean into that method, eg:

@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;
   }
}

Altenatively, if you want to keep the @Bean method in the filter itself, you should replace it by this, since the current object is managed by Spring, while the new instance won't be:

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

Related: Spring @Value annotation always evaluating as null?

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.