写点什么

一篇文章学透 ApplicationContext

作者:小小怪下士
  • 2023-04-23
    湖南
  • 本文字数:3776 字

    阅读完需:约 12 分钟

BeanFactory 与 ApplicationContext 关系的分析

BeanFactory 是 Spring 中最基本的接口,它是 Spring IoC 容器中最底层的接口,提供了 IoC 容器最基本的形式,它具有最基本的 IoC 功能,负责管理 Spring Bean 的生命周期,通过 BeanFactory 可以获取指定 Bean 的实例。 ApplicationContext 是 BeanFactory 的子接口,ApplicationContext 继承了 BeanFactory 接口的全部功能,同时还提供了其他的一些功能。ApplicationContext 是 Spring 中最重要的接口之一,它是 Spring 容器的具体实现,在 BeanFactory 的基础上添加了一些更加实用的功能,比如资源加载、事件发布、AOP 和事务等。 因此,可以认为 ApplicationContext 继承了 BeanFactory,拥有了更多的功能和扩展性。

ApplicationContext 继承的接口与功能

  1. ResourceLoader:加载资源文件

  2. MessageSource:国际化消息的源头

  3. ApplicationEventPublisher:应用事件发布

  4. EnvironmentCapable:获取当前应用的环境信息

  5. ListableBeanFactory:提供了批量操作 Bean 的方法

  6. HierarchicalBeanFactory:层次性的 BeanFactory,支持子容器

  7. AutowireCapableBeanFactory:Bean 自动装配的 BeanFactory

  8. BeanDefinitionRegistry:定义和注册 BeanDefinition 的接口

  9. ConfigurableApplicationContext:ApplicationContext 可配置的接口,对外提供了修改 bean 定义、激活环境、注册 shut-down hook 等能力。

BeanFactory 应用代码示例

public class TestBean {     private String name;     public TestBean() {        System.out.println("constructor of TestBean is invoked");     }     public void setName(String name) {        this.name = name;     }     public String getName() {        return name;     } } public class BeanFactoryExample {     public static void main(String[] args) {         Resource resource = new ClassPathResource("spring-config.xml");         BeanFactory factory = new XmlBeanFactory(resource);         TestBean testBean = (TestBean) factory.getBean("testBean");         System.out.println("The name is : " + testBean.getName());     } } 复制代码
复制代码

其中,ClassPathResource 是一个用于从 classpath 中加载资源文件的类。XmlBeanFactory 是 Spring 提供的一个实现了 BeanFactory 接口的 IoC 容器实例。在实例化 XmlBeanFactory 时,需要提供一个 Resource 对象,这里传入的是 spring-config.xml 文件。

ApplicationContext 各功能的应用代码示例

ResourceLoader 接口的示例

public class ResourceLoaderExample {      public static void main(String[] args) throws IOException {          ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");          ResourceLoader loader = context;          Resource resource = loader.getResource("classpath:test.txt");          InputStream inputStream = resource.getInputStream();          BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));          String line;          while ((line = reader.readLine()) != null) {             System.out.println(line);          }          reader.close();     } } 复制代码
复制代码

这段示例代码通过ApplicationContext实例化了一个ResourceLoader对象,然后通过getResource方法加载了"classpath:test.txt"文件。这个文件在 classpath 路径下,所以可以使用 classpath: 前缀来定位文件。

MessageSource 接口的示例

首先,需要在 Spring 配置文件中定义一个资源文件:

<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">     <property name="basename" value="messages" /></bean> 复制代码
复制代码

然后,在 Java 代码中使用注入方式获取 MessageSource 实例:

public class MessageSourceExample {     public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");        MessageSource messageSource = (MessageSource) context.getBean("messageSource");       String message = messageSource.getMessage("test", null, Locale.getDefault());       System.out.println("The message is : " + message);     } } 复制代码
复制代码

这个示例代码中,我们通过 messageSource.getMessage("test", null, Locale.getDefault()) 方法根据当前默认的语言获取了 messages.propertiestest 属性的值。

ApplicationEventPublisher 接口的示例

我们可以在启动时发布一个事件:

public class MyApplicationEvent extends ApplicationEvent {      public MyApplicationEvent(Object source) {          super(source);      } } public class PublishEventExample {      public static void main(String[] args) {          ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");          context.addApplicationListener(new ApplicationListener<MyApplicationEvent>() {             @Override              public void onApplicationEvent(MyApplicationEvent event) {                 System.out.println("MyApplicationEvent received!");              }          });          context.publishEvent(new MyApplicationEvent("Hello World!"));          context.close();    } } 复制代码
复制代码

当程序成功运行时,我们可以看到输出了 MyApplicationEvent received! 的信息。

EnvironmentCapable 接口的示例

这个接口用于获取当前运行的环境信息:

public class EnvironmentExample {     public static void main(String[] args) {          ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");          Environment environment = context.getEnvironment();          System.out.println("The environment is : " + environment.getProperty("os.name"));     } } 复制代码
复制代码

ListableBeanFactory 接口示例

这个接口中提供了一些批量操作 Bean 的方法:

public class ListableBeanFactoryExample {     public static void main(String[] args) {        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");        ListableBeanFactory beanFactory = context.getBeanFactory();        String[] beanNames = beanFactory.getBeanDefinitionNames();        for (String beanName : beanNames) {            System.out.println(beanName);        }    } } 复制代码
复制代码

AutowireCapableBeanFactory 接口示例

这个接口用于完成 Bean 的自动装配:

public class AutowireCapableBeanFactoryExample {     public static void main(String[] args) {         ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");         AutowireCapableBeanFactory beanFactory = context.getAutowireCapableBeanFactory();        TestBean testBean = new TestBean();         beanFactory.autowireBean(testBean);         System.out.println("The name is : " + testBean.getName());     } } 复制代码
复制代码

BeanDefinitionRegistry 接口示例

这个接口用于注册 Bean:

public class BeanDefinitionRegistryExample {     public static void main(String[] args) {         XmlBeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));         BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;        BeanDefinition beanDefinition = new RootBeanDefinition(TestBean.class);         registry.registerBeanDefinition("testBean", beanDefinition);         TestBean testBean = (TestBean) beanFactory.getBean("testBean");        System.out.println("The name is : " + testBean.getName());     } } 复制代码
复制代码

这个示例代码中,我们通过 BeanDefinitionRegistry 接口实现了向容器注册 TestBean 的过程。

ConfigurableApplicationContext 接口示例

这个接口用于修改 bean 定义、激活环境、注册 shut-down hook 等能力:

public class ConfigurableApplicationContextExample {     public static void main(String[] args) {        ConfigurableApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");        ConfigurableEnvironment environment = context.getEnvironment();        environment.setActiveProfiles("dev");        context.refresh();        TestBean testBean = (TestBean) context.getBean("testBean");        System.out.println("The name is : " + testBean.getName());    } }复制代码
复制代码

在这个示例代码中,我们通过 ConfigurableApplicationContext 接口修改了当前的运行环境,激活了 dev 配置文件并重新刷新了容器,然后获取了 testBean 的实例并输出它的名称。

用户头像

还未添加个人签名 2022-09-04 加入

热衷于分享java技术,一起交流学习,探讨技术。 需要Java相关资料的可以+v:xiaoyanya_1

评论

发布
暂无评论
一篇文章学透ApplicationContext_Java_小小怪下士_InfoQ写作社区