本文主要简述如何在一般的 JAVA 类 (没有被 Spring IOC 容器管理的) 中获取被容器中的 Bean.
虽然测试用例是用 Spring Boot Test 跑的, 但是特性本文介绍的特性主体是 Spring 的, 所以归类到 Spring 专栏中…
如果什么都不做的话, 我们在一般 JAVA 类中注入一个容器 Bean 是无效的, 无法注入, 例如:
public class NormalObject {
private ComponentInIocContainer componentInIocContainer;
public void call() {
System.out.println("直接在普通类中注入被 Spring IOC 容器管理的 Bean...");
Optional.ofNullable(componentInIocContainer).orElseThrow(() -> new RuntimeException("ComponentInIocContainer is null!")).when();
}
@Autowired
public void setComponentInIocContainer(ComponentInIocContainer componentInIocContainer) {
this.componentInIocContainer = componentInIocContainer;
}
}
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationContextTest {
@Test
public void getBean() {
new NormalObject().call();
}
}
运行可以看到空指针异常.
但是实际是, 在某些特定的情况下, 确实需要在一般 JAVA 类中获取被 Spring IOC 容器管理的 Bean, 这个时候, org.springframework.context.ApplicationContext
的作用就体现出来了, 它能实现这个需求, 且看代码:
@Component
public final class ApplicationContext implements ApplicationContextAware {
private static org.springframework.context.ApplicationContext context;
@Override
public void setApplicationContext(@NonNull org.springframework.context.ApplicationContext applicationContext) throws BeansException {
ApplicationContext.context = applicationContext;
}
/**
* Description: 手动获得 Bean
*
* @param genericBeanClass Bean 的 Class 对象
* @return GenericBean
* @author LiKe
* @date 2019-07-30 16:43:09
*/
public static <GenericBean> GenericBean getBean(Class<GenericBean> genericBeanClass) {
return context.getBean(genericBeanClass);
}
}
public class NormalObject {
private ComponentInIocContainer componentInIocContainer;
public void call() {
System.out.println("利用 ApplicationContext 访问被 Spring IOC 容器管理的 Bean...");
ApplicationContext.getBean(ComponentInIocContainer.class).when();
System.out.println("直接在普通类中注入被 Spring IOC 容器管理的 Bean...");
Optional.ofNullable(componentInIocContainer).orElseThrow(() -> new RuntimeException("ComponentInIocContainer is null!")).when();
}
@Autowired
public void setComponentInIocContainer(ComponentInIocContainer componentInIocContainer) {
this.componentInIocContainer = componentInIocContainer;
}
}
同样执行测试用例, 可以看到输出:
利用 ApplicationContext 访问被 Spring IOC 容器管理的 Bean...
The time is: Thu Aug 27 11:26:42 CST 2020
直接在普通类中注入被 Spring IOC 容器管理的 Bean...
java.lang.RuntimeException: ComponentInIocContainer is null!
- END -