Spring Bean注入或替换

1、ApplicationContext

一个比较另类的方法,反射出内部容器Map进行替换,不建议使用。

@Component
public class ApplicationContextUtil implements ApplicationContextAware {

    private String packageName = "com";
    private static ApplicationContext applicationContext = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextUtil.applicationContext = applicationContext;

        Reflections f = new Reflections(packageName);
        Set<Class<?>> set = f.getTypesAnnotatedWith(Config.class);
        for (Class<?> clazz : set) {
            try {
                Object proxy = ProxyBeanFactory.getProxy(clazz);
                String beanName = StringUtils.uncapitalize(clazz.getSimpleName());
                replaceBean(beanName, proxy);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        

    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

  //替换bean
    public static void replaceBean(String beanName, Object targetObj) throws NoSuchFieldException, IllegalAccessException {
        ConfigurableApplicationContext context = (ConfigurableApplicationContext) getApplicationContext();
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) context.getBeanFactory();
        //反射获取Factory中的singletonObjects 将该名称下的bean进行替换
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        singletonObjects.setAccessible(true);
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        map.put(beanName, targetObj);
    }
}

2、BeanDefinitionRegistry

实现 BeanDefinitionRegistryPostProcessor 获取 BeanDefinitionRegistry,可以对Bean进行处理。

@Component
class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Book.class).getBeanDefinition();

        registry.registerBeanDefinition("book", beanDefinition);
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        Book bean = beanFactory.getBean(Book.class);
        bean.setName("a");
    }

}

3、FactoryBean

实现 FactoryBean 可以返回自己创建的对象,可以用于代理对象替换。

@Component
public class ServiceFactoryBean<T> implements FactoryBean<T> {

    private Class<T> clazz;

    public ServiceFactoryBean(Class<T> clazz) {
        this.clazz = clazz;
    }

    @Override
    public T getObject() throws Exception {
        return clazz.newInstance();
    }

    @Override
    public Class<?> getObjectType() {
        return clazz;
    }

    @Override
    public boolean isSingleton() {
        return true;
    }
}