Ensure single instance of a spring managed bean

后端 未结 3 1184
执笔经年
执笔经年 2021-01-16 13:05

I have created a spring aspect to handle Retry mechanism. I have also created a Retry annotation. Following is the code for Retry annotation and an aspect which processes th

相关标签:
3条回答
  • 2021-01-16 13:32
    1. if someone can create second bean of your type, why you are don't want to check someone creates another aspect with same logic? I think your approach is erroneous by design.
    2. you can implement ApplicationContextAware interface and check there, that only one bean of your class present in context and throw exception if it's not true, but I'm not sure that this will work if you have context hierarchy.
    0 讨论(0)
  • 2021-01-16 13:43

    I found a way to do this :) Ref: Going Beyond DI I registered a BeanDefinitionRegistryPostProcessor in my root context, this will ensure that there is only one BeanDefinition of my desired class.

    package test;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
    
    import com.xx.xx.xx.xx.xx.RetryInterceptor;
    
    public class TestBeanFacotryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    
        @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        }
    
        @Override
        public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
            String[] definitionNames = registry.getBeanDefinitionNames();
            for (int i = 0, j = 0; i < definitionNames.length; i++) {
                Class<?> clazz;
                try {
                    clazz = Class.forName(registry.getBeanDefinition(definitionNames[i]).getBeanClassName());
                    if (RetryInterceptor.class == clazz && j++ > 0) {
                        registry.removeBeanDefinition(definitionNames[i]);
                    }
                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    0 讨论(0)
  • 2021-01-16 13:43

    There will ever only be one instance as its a spring managed bean with the default scope of singleton. You have some singleton type stuff at the top of your class (like where you create your new instance statically etc)... this is not needed. An aspect is just a bean like any other so code it asuch. If you want to be sure, put in a PostContruct method with some logging like 'Initiating aspect' or something and you will see it only prints to your logs once.

    0 讨论(0)
提交回复
热议问题