一篇文章学透ApplicationContext

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 的实例并输出它的名称。

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值