Spring Bean 的动态创建获取删除

  1. 一、正常流程的代码
  2. 二、改造动态的创建Sevice

作者:小P不是Peppa;来源:https://mp.weixin.qq.com/s/VZ09N_aLqtJ1etPfNKcUgA

一、正常流程的代码

这个Demo实现数据的简单查询

@RestController
public class TestController {
    @Autowired
    TestService testService;

    @GetMapping("/get")
    public String get() {
        return testService.get();
    }
}

@Service
public class TestService {
    @Autowired
    TestRepository testRepository;
    public String get() {
        return testRepository.get();
    }
}

@Component
public class TestRepository {
    public String get() {
        return "test service";
    }
}

二、改造动态的创建Sevice

上述demo中,不论controller,service还是dao,都有一个共同点,那就是它们都交由spring容器来管理(@RestController、@Service、@Repository)和依赖注入(@Autowired),在容器刷新完成之后这些Bean已经生成并完成了依赖注入,但是现在有一个问题,我不想让它们这么快生成,而是想在后续用到的时候再生成,并且用完后删除,再用到的时候再创建,这时候应该怎么做?

1、把service改动下

去掉@Service注解,不让容器管理,同时去掉依赖注入,提供set方法方便后续设置dao属性

2、提供一个动态生成、查询、删除service的类和一个对应的controller便于访问

import com.example.demo.dao.WinnersDao;
import com.example.demo.service.WinnersService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class DynamicFactory implements BeanFactoryAware, ApplicationContextAware {

    private ApplicationContext applicationContext;

    private DefaultListableBeanFactory beanFactory;

    public WinnersService dynamicGetWinnerService() {
        WinnersService winnersService = null;
        try {
            winnersService = beanFactory.getBean("winnersService", WinnersService.class);
            log.info("获取到的winnersService为:" + winnersService);
        } catch (Exception e) {
            log.info("dynamicGetWinnerService error==>" + e.getMessage());
        }
        return winnersService;
    }

    /**
     * 动态注册bean
     */
    public void dynamicCreateWinnerService() {
        try {
            /**
             * 创建bean定义,设置属性winnersDao,前提是winnersDao已经被spring管理了
             */
            BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(WinnersService.class);
            beanDefinitionBuilder.addPropertyReference("winnersDao", "winnersDao");
            beanFactory.registerBeanDefinition("winnersService", beanDefinitionBuilder.getRawBeanDefinition());
            log.info("创建winnersService......");
        } catch (Exception e) {
            log.error("dynamicCreateWinnerService error==>" + e.getMessage());
        }
    }

    /**
     * 动态销毁bean
     */
    public void dynamicDestroyBean() {
        try {
            beanFactory.destroySingleton("winnersService");
            beanFactory.removeBeanDefinition("winnersService");
            log.info("销毁winnersService......");
        } catch (Exception e) {
            log.error("dynamicDestroyBean error==>" + e.getMessage());
        }
    }


    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = (DefaultListableBeanFactory) beanFactory;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}
package com.example.demo.controller;

import com.example.demo.custom.DynamicFactory;
import com.example.demo.service.WinnersService;
import com.example.demo.vo.WinnersVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/dynamic")
public class DynamicController {

    @Autowired
    private DynamicFactory dynamicFactory;

    @RequestMapping("createBean")
    public String createBean() {
        dynamicFactory.dynamicCreateWinnerService();
        return "createBean success";
    }

    @RequestMapping("destroyBean")
    public String destroyBean() {
        dynamicFactory.dynamicDestroyBean();
        return "destroyBean success";
    }
}

3、改造controller,注入DynamicFactory,后续通过它获取service


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 8629303@qq.com

×

喜欢就点赞,疼爱就打赏

GitHub