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 {@Autowiredprivate ApplicationContext context;private DefaultListableBeanFactory factory;@PostConstructpublic 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容器内对象的销毁、注册、替换等目的。