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;
}
}