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?
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:
@Component annotationFilterRegistrationBean 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?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With