Spring中动态注册和销毁对象

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 beanDefinitionList = Arrays.asList(factory.getBeanDefinitionNames());
        if (beanDefinitionList.contains(beanName)) {
            factory.destroySingleton(beanName);
        }

        for (Iterator it = factory.getBeanNamesIterator();it.hasNext();) {
            String next = it.next();
            if (next.equals(beanName)) {
                factory.removeBeanDefinition(beanName);
                return;
            }
        }
    }

    /**
     * 获取bean
     *
     * @param clazz
     * @return
     * @param 
     */
    public  T getBean(String name, Class clazz) {
        for(Iterator 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 初次运行

Spring中动态注册和销毁对象_第1张图片

3.2 注册bean

使用addUser注册后,使用get方法获取容器内中的user对象,结果如下:

Spring中动态注册和销毁对象_第2张图片

Spring中动态注册和销毁对象_第3张图片

3.3 再次注册,覆盖对象

销毁已存在的对象,重新注册对象。使用get方法获取容器内中的user对象,结果如下:

Spring中动态注册和销毁对象_第4张图片

Spring中动态注册和销毁对象_第5张图片

4. 总结

        通过removeBean方法和registerBean结合,可以达到spring容器内对象的销毁、注册、替换等目的。

你可能感兴趣的:(spring,spring,java)