springboot复制bean_SpringBoot动态注入及操作Bean

本文介绍了如何在SpringBoot中动态注入、修改和删除Bean。通过BeanFactory和BeanDefinitionBuilder,可以实现在运行时注册、更新和移除Bean。
摘要由CSDN通过智能技术生成

在Spring中我们通过getBean来获得对象,但这些对象都是事先定义好的,如果需要操作事先未定义的Bean就需要动态注入、修改和删除Bean

思路

在Spring中,BeanFactory负责管理Bean,具体来说是DefaultListableBeanFactory,我们只需要获取到当前上下文中的BeanFactory,就能执行其中的注册Bean的方法registerBeanDefinition,注册Bean时需要Bean的信息,Spring提供了BeanDefinitionBuilder.genericBeanDefinition()方法来构建BeanDefinition,用这些方法就可以实现Bean的动态注入

代码实现

测试服务类TestService

创建一个测试类来测试Bean的操作,这个类上没有加注解,Spring在加载时不会自动注入package com.mantis.bean.service;

/**

* @Description:

* @author: wei.wang

* @since: 2020/9/17 12:53

* @history: 1.2020/9/17 created by wei.wang

*/

public class TestService {

private String name;

private String id;

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public void print() {

System.out.println("获取bean,name=" + name + ",id=" + id);

}

@Override

public String toString() {

return "TestService{" +

"name='" + name + '\'' +

", id='" + id + '\'' +

'}';

}

}

SpringContextUtil类

操作Bean的Util类,其中上线文ApplicationContext在SpringBoot启动时设置,也可以直接使用Autowired注入或者根据具体项目具体实现package com.mantis.bean.util;

import org.springframework.beans.factory.NoSuchBeanDefinitionException;

import org.springframework.context.ApplicationContext;

/**

* @Description:

* @author: wei.wang

* @since: 2020/9/17 12:52

* @history: 1.2020/9/17 created by wei.wang

*/

public class SpringContextUtil {

private static ApplicationContext applicationContext;

//获取上下文

public static ApplicationContext getApplicationContext() {

return applicationContext;

}

//设置上下文

public static void setApplicationContext(ApplicationContext applicationContext) {

SpringContextUtil.applicationContext = applicationContext;

}

//通过名字获取上下文中的bean

public static Object getBean(String name) {

try {

return applicationContext.getBean(name);

} catch (NoSuchBeanDefinitionException ex) {

return null;

}

}

//通过类型获取上下文中的bean

public static Object getBean(Class> requiredType) {

return applicationContext.getBean(requiredType);

}

}

启动类SpringBootBeanApplication

在启动类上设置上下文package com.mantis.bean;

import com.mantis.bean.util.SpringContextUtil;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.ApplicationContext;

@SpringBootApplication

public class SpringBootBeanApplication {

public static void main(String[] args) {

ApplicationContext app = SpringApplication.run(SpringBootBeanApplication.class, args);

SpringContextUtil.setApplicationContext(app);

}

}

注入Bean

向Spring上下文中注入Bean,注入前先检查Bean是否已经存在/**

* 注册Bean

*

* @return

*/

@GetMapping("/bean/register/{beanName}")

public String registerBean(@PathVariable String beanName) {

//获取context

ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();

//获取BeanFactory

DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();

//创建bean信息.

BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(TestService.class);

beanDefinitionBuilder.addPropertyValue("id", "1");

beanDefinitionBuilder.addPropertyValue("name", "张三");

//判断Bean是否已经注册

Object beanObject = SpringContextUtil.getBean(beanName);

if (beanObject != null) {

System.out.println(String.format("Bean %s 已注册", beanName));

} else {

//动态注册bean.

defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());

//获取动态注册的bean.

beanObject = SpringContextUtil.getBean(beanName);

if (beanObject != null) {

System.out.println(String.format("Bean %s 注册成功", beanName));

return beanObject.toString();

} else {

return "register Bean Error";

}

}

return "register Bean Success";

}

修改Bean

从SpringContext中获取到指定Bean的Class对象,获取到之后就可以根据字段进行赋值/**

* 动态修改Bean

*

* @return

*/

@GetMapping("/bean/update/{beanName}")

public String update(@PathVariable String beanName) {

ApplicationContext applicationContext = SpringContextUtil.getApplicationContext();

String[] beans = applicationContext.getBeanDefinitionNames();

for (String bean : beans) {

// 拿到bean的Class对象

Class> beanType = applicationContext.getType(bean);

if (beanType == null) {

continue;

}

// 拿到当前bean类型的所有字段

Field[] declaredFields = beanType.getDeclaredFields();

if (beanName.equals(bean)) {

for (Field field : declaredFields) {

// 从spring容器中拿到这个具体的bean对象

Object beanObject = applicationContext.getBean(bean);

// 当前字段设置新的值

try {

String fieldName = field.getName();

if ("name".equals(fieldName)) {

setFieldData(field, beanObject, "AL113A5");

} else if ("id".equals(fieldName)) {

setFieldData(field, beanObject, "12");

}

} catch (Exception e) {

e.printStackTrace();

}

}

}

}

return "update Bean Success";

}

private void setFieldData(Field field, Object bean, String data) throws Exception {

field.setAccessible(true);

Class> type = field.getType();

if (type.equals(String.class)) {

field.set(bean, data);

} else if (type.equals(Integer.class)) {

field.set(bean, Integer.valueOf(data));

} else if (type.equals(Long.class)) {

field.set(bean, Long.valueOf(data));

} else if (type.equals(Double.class)) {

field.set(bean, Double.valueOf(data));

} else if (type.equals(Short.class)) {

field.set(bean, Short.valueOf(data));

} else if (type.equals(Byte.class)) {

field.set(bean, Byte.valueOf(data));

} else if (type.equals(Boolean.class)) {

field.set(bean, Boolean.valueOf(data));

} else if (type.equals(Date.class)) {

field.set(bean, new Date(Long.parseLong(data)));

}

}

移除Bean

将Bean从Spring上下文中移除/**

* 移除Bean

*

* @return

*/

@GetMapping("/bean/remove/{beanName}")

public String removeBeanDefinition(@PathVariable String beanName) {

Object beanObject = SpringContextUtil.getBean(beanName);

if (beanObject == null) {

System.out.println(String.format("Bean %s 不存在", beanName));

return "remove Error";

}

//获取context.

ConfigurableApplicationContext configurableApplicationContext = (ConfigurableApplicationContext) SpringContextUtil.getApplicationContext();

//获取BeanFactory

DefaultListableBeanFactory defaultListableBeanFactory = (DefaultListableBeanFactory) configurableApplicationContext.getBeanFactory();

defaultListableBeanFactory.removeBeanDefinition(beanName);

System.out.println(String.format("Bean %s 已移除", beanName));

return "remove Success";

}

测试

写一个操作Bean的方法/**

* 操作Bean

*

* @return

*/

@GetMapping("/bean/print/{beanName}")

public String print(@PathVariable String beanName) {

Object beanObject = SpringContextUtil.getBean(beanName);

if (beanObject != null) {

((TestService) beanObject).print();

return beanObject.toString();

} else {

System.out.println(String.format("Bean %s 不存在", beanName));

}

return String.format("Bean %s 不存在", beanName);

}

注册

调用方法localhost:9000/bean/register/TestService

结果

执行操作Bean的方法,返回结果如下TestService{name='张三', id='1'}

修改

调用方法localhost:9000/bean/update/TestService

结果

执行操作Bean的方法,返回结果如下TestService{name='AL113A5', id='12'}

移除

调用方法localhost:9000/bean/remove/TestService

结果

执行操作Bean的方法,返回结果如下Bean TestService 不存在

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值