01.容器接口BeanFactory和ApplicationContext
容器接口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又继承了DefaultSingletonBeanRegistryField 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 : 发送短信