容器接口BeanFactory和ApplicationContext
- BeanFactory能做哪些事
- ApplicationContext有哪些扩展功能
- 事件解耦
重点
到底什么是BeanFactory
- 它是 ApplicationContext 的父接口
- 它才是 Spring 的核心容器, 主要的 ApplicationContext 实现都【组合】了它的功能
BeanFactory 能干点啥
- 表面上只有 getBean
- 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类提供
ApplicationContext扩展了哪些功能
扩展了以下接口:MessageSource、ResourcePatternResolver、EnvironmentCapable、ApplicationEventPublisher
MessageSource的getMessage方法:用来翻译多国语言,提供翻译能力
ResourcePatternResolver的getResources:提供使用通配符来匹配资源的能力
EnvironmentCapable的getEnvironment方法:提供获取环境变量的能力
ApplicationEventPublisher的pulishEven方法:发布事件的能力
代码
/*
BeanFactory 与 ApplicationContext 的区别
*/
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, DruidDataSourceAutoConfigure.class})
public class A01 {
private static final Logger log = LoggerFactory.getLogger(A01.class);
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, IOException {
ConfigurableApplicationContext context = SpringApplication.run(A01.class, args);
// 在这里打断点可以看到context里有BeanFactory对象
// context.getBean("aaa");
System.out.println(context);
/*
2. BeanFactory 能干点啥
- 表面上只有 getBean
- 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类提供
*/
// BeanFactory实际上是DefaultListableBeanFactory类型,DefaultListableBeanFactory又继承了DefaultSingletonBeanRegistry
Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
singletonObjects.setAccessible(true);
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// get方法,传入该Field的类类型对象,返回该队形中的该字段值
Map<String, Object> o = (Map<String, Object>) singletonObjects.get(beanFactory);
o.forEach((key, value) -> {
if (!key.startsWith("component")) {
return;
}
System.out.println(key + "-----" + value);
});
/*
3. ApplicationContext 比 BeanFactory 多点啥
*/
// MessageSource:用来翻译多国语言,提供翻译能力
System.out.println(context.getMessage("hi", null, Locale.CHINA));
System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
System.out.println(context.getMessage("hi", null, Locale.JAPANESE));
// ResourcePatternResolver:提供使用通配符来匹配资源的能力
// classpath和classpath*的区别
// Resource[] resources = context.getResources("classpath:META-INF/spring.factories");
Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
for (Resource resource : resources) {
System.out.println(resource);
}
// EnvironmentCapable:提供获取环境变量的能力
System.out.println(context.getEnvironment().getProperty("java_home"));
System.out.println(context.getEnvironment().getProperty("server.port"));
// ApplicationEventPublisher:发布事件的能力
context.publishEvent(new UserRegisteredEvent(context));
// context.getBean(Component1.class).register();
}
component1-----com.shunyum.a01.Component1@4a0df195
component2-----com.shunyum.a01.Component2@42fcc7e6
���
Hello
����ˤ���
URL [jar:file:/E:/Maven/repository/repository/org/springframework/boot/spring-boot/2.5.5/spring-boot-2.5.5.jar!/META-INF/spring.factories]
URL [jar:file:/E:/Maven/repository/repository/org/springframework/boot/spring-boot-autoconfigure/2.5.5/spring-boot-autoconfigure-2.5.5.jar!/META-INF/spring.factories]
URL [jar:file:/E:/Maven/repository/repository/org/springframework/spring-beans/5.3.23/spring-beans-5.3.23.jar!/META-INF/spring.factories]
URL [jar:file:/E:/Maven/repository/repository/org/mybatis/spring/boot/mybatis-spring-boot-autoconfigure/2.2.0/mybatis-spring-boot-autoconfigure-2.2.0.jar!/META-INF/spring.factories]
URL [jar:file:/E:/Maven/repository/repository/com/alibaba/druid-spring-boot-starter/1.2.8/druid-spring-boot-starter-1.2.8.jar!/META-INF/spring.factories]
URL [jar:file:/E:/Maven/repository/repository/org/springframework/spring-test/5.3.23/spring-test-5.3.23.jar!/META-INF/spring.factories]
E:\JAVA\Java
8080
2023-04-06 23:44:01.778 DEBUG 15040 --- [ main] com.shunyum.a01.Component2 : com.shunyum.a01.UserRegisteredEvent[source=org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@649bec2e, started on Thu Apr 06 23:44:00 CST 2023]
2023-04-06 23:44:01.779 DEBUG 15040 --- [ main] com.shunyum.a01.Component2 : 发送短信