1. 使用说明
通常我们项目中想要往spring容器中注入一个bean可以在项目初始化的时候结合@Bean注解实现。但是该方法适合项目初始化时候使用,如果后续想要继续注入对象则无可奈何。本文主要描述一种在后续往spring容器注入bean的方法。
2. 实现
2.1 说明
2.1.1 注册bean
- 定义BeanDefinition,注册类定义到factory中
- 创建对象,注册实例到fatory中
2.1.2 销毁bean
- 判断是否有类定义。有,则移除BeanDefinition
- 判断是否有对象。有,则从容器中去除
2.2 代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
/**
* @author pp_lan
* @date 2024/1/17
*/
@Component
public class SpringUtils {
@Autowired
private ApplicationContext context;
private DefaultListableBeanFactory factory;
@PostConstruct
public void init() {
factory = (DefaultListableBeanFactory) context.getAutowireCapableBeanFactory();
}
/**
* 注册对象
*
* @param beanName
* @param object
*/
public void registerBean(String beanName, Object object) {
// 添加类定义
factory.registerBeanDefinition(beanName, new RootBeanDefinition(object.getClass()));
// 添加类实例
factory.registerSingleton(beanName, object);
}
/**
* 删除对象
*
* @param beanName
*/
public void removeBean(String beanName) {
List<String> beanDefinitionList = Arrays.asList(factory.getBeanDefinitionNames());
if (beanDefinitionList.contains(beanName)) {
factory.destroySingleton(beanName);
}
for (Iterator<String> it = factory.getBeanNamesIterator();it.hasNext();) {
String next = it.next();
if (next.equals(beanName)) {
factory.removeBeanDefinition(beanName);
return;
}
}
}
/**
* 获取bean
*
* @param clazz
* @return
* @param <T>
*/
public <T> T getBean(String name, Class<T> clazz) {
for(Iterator<String> it = factory.getBeanNamesIterator();it.hasNext();) {
String next = it.next();
if (next.equals(name)) {
return this.context.getBean(name, clazz);
}
}
return null;
}
}
2.3 测试代码
@RequestMapping("/addUser")
public Response add(String userId) {
User user = new User(userId, "zhang", "小张");
springUtils.removeBean("user");
springUtils.registerBean("user", user);
User zhang = springUtils.getBean("user", User.class);
return Response.ok(zhang);
}
@RequestMapping("/get")
public Response get() {
return Response.ok(springUtils.getBean("user", User.class));
}
3. 运行
3.1 初次运行
3.2 注册bean
使用addUser注册后,使用get方法获取容器内中的user对象,结果如下:
3.3 再次注册,覆盖对象
销毁已存在的对象,重新注册对象。使用get方法获取容器内中的user对象,结果如下:
4. 总结
通过removeBean方法和registerBean结合,可以达到spring容器内对象的销毁、注册、替换等目的。