!388 修复registerBean中@Autowired无效的问题

Merge pull request !388 from 晴雨夜/v5-dev
This commit is contained in:
Looly 2021-08-01 00:39:52 +00:00 committed by Gitee
commit e931a45722
2 changed files with 112 additions and 2 deletions

View File

@ -4,8 +4,10 @@ import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ArrayUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.DefaultSingletonBeanRegistry;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
@ -189,6 +191,8 @@ public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextA
* 动态向Spring注册Bean
* <p>
* {@link org.springframework.beans.factory.BeanFactory} 实现通过工具开放API
* <p>
* 更新: shadow 2021-07-29 17:20:44 增加自动注入修复注册bean无法反向注入的问题
*
* @param <T> Bean类型
* @param beanName 名称
@ -197,13 +201,52 @@ public class SpringUtil implements BeanFactoryPostProcessor, ApplicationContextA
* @since 5.4.2
*/
public static <T> void registerBean(String beanName, T bean) {
if(null != beanFactory){
if (null != beanFactory) {
beanFactory.autowireBean(bean);
beanFactory.registerSingleton(beanName, bean);
} else if(applicationContext instanceof ConfigurableApplicationContext){
} else if (applicationContext instanceof ConfigurableApplicationContext) {
ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
AutowireCapableBeanFactory factory = context.getAutowireCapableBeanFactory();
factory.autowireBean(bean);
context.getBeanFactory().registerSingleton(beanName, bean);
}
}
/**
* 注销bean
* <p>
* 将Spring中的bean注销请谨慎使用
*
* @param beanName bean名称
* @author shadow
* @since 5.7.7
*/
public static void unRegisterBean(String beanName) {
if (applicationContext instanceof ConfigurableApplicationContext) {
ConfigurableApplicationContext context = (ConfigurableApplicationContext) applicationContext;
DefaultSingletonBeanRegistry registry = (DefaultSingletonBeanRegistry) context.getBeanFactory();
registry.destroySingleton(beanName);
}
}
/**
*
* 替换Bean
* 组合{@link SpringUtil#unRegisterBean(String)} {@link SpringUtil#replaceBean(String, Object)}
* 将Spring持有bean先注销再注册
* 需要注意的替换Bean的内部对象的指针指向并不会变化
* 所有替换的bean被持有的情况下需要有下至上逐步替换
*
* @param beanName bean名称
* @param bean bean
* @param <T> 泛型
* @author shadow
* @since 5.7.7
*/
/*public static <T> void replaceBean(String beanName, T bean) {
unRegisterBean(beanName);
registerBean(beanName, bean);
}*/
}

View File

@ -6,10 +6,13 @@ import lombok.Data;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;
@ -33,6 +36,57 @@ public class SpringUtilTest {
Assert.assertEquals("222", registerBean2.getName());
}
/**
* 测试自动注入
*/
@Test
public void registerBeanTest2() {
TestAutoWired testAutoWired = new TestAutoWired();
TestBean testBean = new TestBean();
testBean.setId("123");
SpringUtil.registerBean("testBean", testBean);
SpringUtil.registerBean("testAutoWired", testAutoWired);
testAutoWired = SpringUtil.getBean("testAutoWired");
Assert.assertNotNull(testAutoWired);
Assert.assertNotNull(testAutoWired.getAutowiredBean());
Assert.assertEquals("123", testAutoWired.getAutowiredBean().getId());
}
/**
* 测试注销bean
*/
@Test
public void unRegisterBeanTest() {
registerBeanTest2();
Assert.assertNotNull(SpringUtil.getBean("testAutoWired"));
SpringUtil.unRegisterBean("testAutoWired1");
try {
SpringUtil.getBean("testAutoWired");
} catch (NoSuchBeanDefinitionException e) {
Assert.assertEquals(e.getClass(), NoSuchBeanDefinitionException.class);
}
}
/**
* 测试替换bean
@Test
public void replaceBeanTest() {
registerBeanTest2();
TestAutoWired testAutoWired = new TestAutoWired();
TestBean testBean = new TestBean();
testBean.setId("222");
Assert.assertEquals("123", SpringUtil.getBean("testBean", TestBean.class).getId());
SpringUtil.replaceBean("testBean", testBean);
SpringUtil.replaceBean("testAutoWired", testAutoWired);
testAutoWired = SpringUtil.getBean("testAutoWired");
TestBean testBean1 = testAutoWired.getAutowiredBean();
Assert.assertEquals("222", testAutoWired.getAutowiredBean().getId());
Assert.assertEquals("222", testBean1.getId());
}*/
@Test
public void getBeanTest(){
final Demo2 testDemo = SpringUtil.getBean("testDemo");
@ -69,4 +123,17 @@ public class SpringUtilTest {
return map;
}
}
@Data
public static class TestAutoWired {
@Autowired
// @Resource
private TestBean autowiredBean;
}
@Data
public static class TestBean {
private String id;
}
}