spring-projects / spring-framework

Spring Framework
https://spring.io/projects/spring-framework
Apache License 2.0
56.75k stars 38.15k forks source link

Numerous warnings when injecting dependencies into configuration that implements CachingConfigurer #33834

Closed ChunGeun-Yu closed 1 week ago

ChunGeun-Yu commented 3 weeks ago

there are following warn messages

Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [meterRegistryPostProcessor]?

following case. CachingConfigurer + redis cache + jcache(ehcache) + actuator

I've built a minimal sample application to reproduce issue: https://github.com/ChunGeun-Yu/cache-issue-report/tree/master

I think this issue is very similar with https://github.com/spring-projects/spring-boot/issues/29053

full message

:: Spring Boot ::                (v3.3.5)

2024-11-01T20:11:04.298+09:00  INFO 135020 --- [report] [           main] c.example.report.IssueReportApplication  : Starting IssueReportApplication using Java 21.0.2 with PID 135020 (E:\workspace\meterregistry-error-report\target\classes started by chung in E:\workspace\meterregistry-error-report)
2024-11-01T20:11:04.300+09:00  INFO 135020 --- [report] [           main] c.example.report.IssueReportApplication  : No active profile set, falling back to 1 default profile: "default"
2024-11-01T20:11:04.982+09:00  INFO 135020 --- [report] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode
2024-11-01T20:11:04.984+09:00  INFO 135020 --- [report] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2024-11-01T20:11:05.004+09:00  INFO 135020 --- [report] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 10 ms. Found 0 Redis repository interfaces.
2024-11-01T20:11:05.185+09:00  WARN 135020 --- [report] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.data.redis-org.springframework.boot.autoconfigure.data.redis.RedisProperties' of type [org.springframework.boot.autoconfigure.data.redis.RedisProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [meterRegistryPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2024-11-01T20:11:05.189+09:00  WARN 135020 --- [report] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration' of type [org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [meterRegistryPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2024-11-01T20:11:05.191+09:00  WARN 135020 --- [report] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'redisConnectionDetails' of type [org.springframework.boot.autoconfigure.data.redis.PropertiesRedisConnectionDetails] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [meterRegistryPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
2024-11-01T20:11:05.196+09:00  WARN 135020 --- [report] [           main] trationDelegate$BeanPostProcessorChecker : Bean 'spring.ssl-org.springframework.boot.autoconfigure.ssl.SslProperties' of type [org.springframework.boot.autoconfigure.ssl.SslProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). Is this bean getting eagerly injected/applied to a currently created BeanPostProcessor [meterRegistryPostProcessor]? Check the corresponding BeanPostProcessor declaration and its dependencies/advisors. If this bean does not have to be post-processed, declare it with ROLE_INFRASTRUCTURE.
...
wilkinsona commented 3 weeks ago

Thanks for the sample.

Proxy-based caching uses an advisor to add advice to beans with cacheable methods. Such advisors are created very early which can lead to problems when injecting dependencies into them or into anything upon which they depend. This is done by Spring Framework and, as such, is out of Spring Boot's control.

In your sample, the advisor depends upon your CacheConfigurer into which you're injecting a RedisConnectionFactory bean. This leads to early initialization of all of the Redis-related infrastructure.

Note that the problem will occur without a dependency on spring-boot-starter-actuator and isn't specifically related to MeterRegistryPostProcessor. I believe it will occur when there is any bean post-processor in the context. For example, without Actuator, the problem still occurs when creating Spring Data's ProjectingArgumentResolverBeanPostProcessor.

You can eliminate the warnings by reworking your CacheConfiguration:

@Configuration
@EnableCaching
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
class CacheConfiguration implements CachingConfigurer {

    private final ObjectProvider<RedisConnectionFactory> redisConnectionFactory;

    CacheConfiguration(ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
        this.redisConnectionFactory = redisConnectionFactory;
    }

        @Bean
    @Override
    public CacheManager cacheManager() {
        return RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(redisConnectionFactory.getObject())
                .build();
    }

}

Using an ObjectProvider when injecting the connection factory defers the creation of the connection factory. Rather than being created when CacheConfiguration is created, the creation's now deferred until the cacheManager() method is called. This addresses all of the warnings for the Redis-related beans. This leaves a single warning about CacheConfiguration itself. This warning can be avoided by assigning the infrastructure role to CacheConfiguration which prevents it from being post-processed.

We'll transfer this to the Framework team for their consideration. For example, it may be useful to provide some guidance in the javadoc of CachingConfigurer.

ChunGeun-Yu commented 3 weeks ago

@wilkinsona Thank you for your detailed explanation.