Spring中动态注册和销毁对象

发布时间:2024年01月17日

1. 使用说明

????????通常我们项目中想要往spring容器中注入一个bean可以在项目初始化的时候结合@Bean注解实现。但是该方法适合项目初始化时候使用,如果后续想要继续注入对象则无可奈何。本文主要描述一种在后续往spring容器注入bean的方法。

2. 实现

2.1 说明

2.1.1 注册bean

  • 定义BeanDefinition,注册类定义到factory中
  • 创建对象,注册实例到fatory中

2.1.2 销毁bean

  • 判断是否有类定义。有,则移除BeanDefinition
  • 判断是否有对象。有,则从容器中去除

2.2 代码

import com.google.common.collect.Lists;
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) {
        List<String> beanNameList = Lists.newArrayList(factory.getBeanNamesIterator());
        if (!beanNameList.contains(name)) {
            return null;
        }
        return this.context.getBean(name, clazz);
    }
}

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容器内对象的销毁、注册、替换等目的。

文章来源:https://blog.csdn.net/pp_lan/article/details/135654348
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。