Skip to content

Document that Filter beans are eagerly initialized #17814

@caspianb

Description

@caspianb

See sample code in branch to reproduce issue: https://github.com/caspianb/SpringBootTest/tree/feature/filter-proxy-bug

I reproduced this issue in at least the following spring boot versions (2.1.0, 2.1.4, 2.1.6, 2.1.7).

Spring is not properly injecting the proxied threadLocalTargetSource for a prototype bean for the first Filter it injects the bean into. It seems ONLY Filter classes have this issue -- if I do not enable filters (e.g. remove @Component annotation from filters) in the above linked project the interceptor and user controller still work properly -- so it does not appear to simply be a "which class was loaded first" issue.

Starting the above sample application and accessing the root page will log output that demonstrates the issue:

  • The first filter loaded by Spring will contain the direct TenantStore bean.
  • Every other component (including the second filter) will properly have the proxiedLocalThreadTargetSource TenantStore bean.

Example of issue:

// First Request
[http-nio-8080-exec-1] INFO  AuthFilterA: 1. TenantStore@1363509553 tenant=null
[http-nio-8080-exec-1] INFO  AuthFilterA: 2. TenantStore@1363509553 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthFilterB: 1. TenantStore@1280546379 tenant=null
[http-nio-8080-exec-1] INFO  AuthFilterB: 2. TenantStore@1280546379 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthInterceptor: 1. TenantStore@1280546379 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthInterceptor: 2. TenantStore@1280546379 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthController: TenantStore@1280546379 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthInterceptor: 3. TenantStore@1280546379 tenant=John Doe
[http-nio-8080-exec-1] INFO  AuthInterceptor: 4. TenantStore@1280546379 tenant=null

// Second Request
[http-nio-8080-exec-3] INFO  AuthFilterA: 1. TenantStore@1363509553 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthFilterA: 2. TenantStore@1363509553 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthFilterB: 1. TenantStore@1703933351 tenant=null
[http-nio-8080-exec-3] INFO  AuthFilterB: 2. TenantStore@1703933351 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthInterceptor: 1. TenantStore@1703933351 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthInterceptor: 2. TenantStore@1703933351 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthController: TenantStore@1703933351 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthInterceptor: 3. TenantStore@1703933351 tenant=John Doe
[http-nio-8080-exec-3] INFO  AuthInterceptor: 4. TenantStore@1703933351 tenant=null

You can see AuthFilterA has a different TenantStore bean than all other beans. Further, this bean is maintained across all requests (since AuthFilterA is a singleton holding onto a simple prototype bean).

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions