怎么获取spring容器?来,总结下!
一、获取spring容器能干啥?
很多时候我们需要获取spring容器,也就是ApplicationContext,获取它有哪些好处呢?
要访问某个 bean 就必须得到一个ApplicationContext 或者 BeanFactory 对象, 比如在ApplicationContext实例化后,同样通过getBean方法从ApplicationContext容器中获取装配好的Bean实例以供使用。
BeanFacotry是spring中比较原始的Factory,ApplicationContext更强大,可以在服务器启动的时候自动实例化所有的bean,而 BeanFactory只有在调用getBean()的时候才去实例化那个bean。简单点说 ApplicationContext 继承自BeanFactory接口,除了包含BeanFactory的所有功能之外,在系统环境、国际化支持、资源访问(如URL和文件)、事件传播等方面进行了良好的支持。
ApplicationContext的中文意思是“应用前后关系”,可以说获取了 ApplicationContext 容器对象就基本拿到了整个spring管理的起来的bean及上下文。
二、怎么获取ApplicationContext容器?
既然ApplicationContext这么重要,如何获取呢?分为以下的情形:
- 在项目启动时获取
- 在代码里获取,比如controller、service等
- 在bean中获取
2.1 在项目启动时获取
@SpringBootApplication
public class ProviderA {
private static ApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(ProviderA.class, args);
Console.log(applicationContext.getBean("carDTO"));
displayAllBeans();
}
public static void displayAllBeans() {
String[] allBeanNames = applicationContext.getBeanDefinitionNames();
Stream.of(allBeanNames).forEach(System.out::println);
}
}
CarDTO(id=1, brand=qq)
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
providerA
org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
restTemplateConfig
importTestConfig
.....
项目启动后就会获取到spring容器。
2.2 在controller里获取
@RestController
@RequestMapping("/dept")
public class DeptController implements ApplicationContextAware {
private WebApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
context = (WebApplicationContext) applicationContext;
}
@GetMapping("/test")
public String[] test() {
String[] beanDefinitionNames = context.getBeanDefinitionNames();
Console.log(context.getBean("carDTO"));
Console.log(context.getApplicationName());
Stream.of(beanDefinitionNames).forEach(System.out::println);
return beanDefinitionNames;
}
}
CarDTO(id=1, brand=qq)
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
providerA
org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory
restTemplateConfig
importTestConfig
.....
2.3 在bean中获取
public class Person implements ApplicationContextAware {
private ApplicationContext applicationContext;
public Person() {
Console.log("Person构造方法!");
}
@PreDestroy
public void destroy(){
Console.log("Person销毁方法!");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
Console.log("容器唯一ID:" + applicationContext.getId());
String[] beanDefinitionNames = applicationContext.getBeanDefinitionNames();
Stream.of(beanDefinitionNames).forEach(System.out::println);
}
}
Person构造方法!
容器唯一ID:org.springframework.context.annotation.AnnotationConfigApplicationContext@7ca48474
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
config
person
补充一:BeanFactory和ApplicationContext有什么区别?
BeanFactory 可以理解为含有Bean集合的工厂类。BeanFactory 包含了bean的定义,以便在接收到客户端请求时将对应的Bean实例化。
BeanFactory还能在实例化对象时生成协作类之间的关系。BeanFactory还包含Bean生命周期的控制,调用客户端的初始化方法(initialization Methods)和销毁方法(destruction Methods)。
从表面上看,ApplicationContext如同Bean Factory一样具有Bean定义、Bean关联关系的设置,以及根据请求分发Bean的功能。但ApplicationContext在此基础上还提供了其他功能。
(1)提供了支持国际化的文本消息。
(2)统一的资源文件读取方式。
(3)已在监听器中注册的Bean的事件。