jarst
jarst

Reputation: 157

Spring ignores @Primary annotation

I've got a code that attempts to override a bean (RedisIndexedSessionRepository) defined in external dependency (spring-session-data-redis:2.2.0).

Here's a full source of a class with bean definition. Relevant part bellow:

@Configuration(proxyBeanMethods = false)
public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguration
        implements BeanClassLoaderAware, EmbeddedValueResolverAware, ImportAware {
    // ...

    @Bean
    public RedisIndexedSessionRepository sessionRepository() {
        // constructs and returns sessionRepository
    }

    // ...

    @EnableScheduling
    @Configuration(proxyBeanMethods = false)
    class SessionCleanupConfiguration implements SchedulingConfigurer {

        private final RedisIndexedSessionRepository sessionRepository;

        SessionCleanupConfiguration(RedisIndexedSessionRepository sessionRepository) {
            this.sessionRepository = sessionRepository;
        }

        // ...
    }
}

And here's a code trying to override the bean:

@EnableRedisHttpSession
@Configuration
public class CustomRedisHttpSessionConfiguration extends RedisHttpSessionConfiguration {
    // ...

    @Bean
    @Primary
    public RedisIndexedSessionRepository customSessionRepository() {
        RedisIndexedSessionRepository sessionRepository = super.sessionRepository();
        // custom config code
        return safeRepository;
    }

    // ...
}

When I attempt to start the application, an error is logged to the console:

Parameter 0 of constructor in org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration$SessionCleanupConfiguration required a single bean, but 2 were found: // lists beans from both classes here Action:

Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

Any ideas why @Primary is not taken into account here?

Upvotes: 0

Views: 2689

Answers (1)

lukascode
lukascode

Reputation: 148

Just add one property to your configuration:

spring.main.allow-bean-definition-overriding=true

EDIT

or try something like that:

@EnableRedisHttpSession
@Configuration
public class CustomRedisHttpSessionConfiguration extends 
    RedisHttpSessionConfiguration implements BeanPostProcessor {
    // ...

    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if (bean.getClass() == RedisIndexedSessionRepository.class) {
            RedisIndexedSessionRepository sessionRepository = (RedisIndexedSessionRepository) bean;
            // custom config code
        }
        return bean;
    }

    // ...
}

Upvotes: 1

Related Questions