百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 文章教程 > 正文

一篇文章学透ApplicationContext

xsobi 2024-11-24 23:33 1 浏览

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.properties 中 test 属性的值。

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


原文链接:https://juejin.cn/post/7224772830779637817

相关推荐

js向对象中添加元素(对象,数组) js对象里面添加元素

一、添加一个元素对象名["属性名"]=值(值:可以是一个值,可以是一个对象,也可以是一个数组)这样添加进去的元素,就是一个值或对象或数组...

JS小技巧,如何去重对象数组?(一)

大家好,关于数组对象去重的业务场景,想必大家都遇到过类似的需求吧,这对这样的需求你是怎么做的呢。下面我就先和大家分享下如果是基于对象的1个属性是怎么去重实现的。方法一:使用.filter()和....

「C/C++」之数组、vector对象和array对象的比较

数组学习过C语言的,对数组应该都不会陌生,于是这里就不再对数组进行展开介绍。模板类vector模板类vector类似于string,也是一种动态数组。能够在运行阶段设置vector对象的长度,可以在末...

如何用sessionStorage保存对象和数组

背景:在工作中,我将[{},{}]对象数组形式,存储到sessionStorage,然后ta变成了我看不懂的形式,然后我想取之用之,发现不可能了~记录这次深刻的教训。$clickCouponIndex...

JavaScript Array 对象 javascript的array对象

Array对象Array对象用于在变量中存储多个值:varcars=["Saab","Volvo","BMW"];第一个数组元素的索引值为0,第二个索引值为1,以此类推。更多有...

JavaScript中的数组Array(对象) js array数组

1:数组Array:-数组也是一个对象-数组也是用来存储数据的-和object不同,数组中可以存储一组有序的数据,-数组中存储的数据我们称其为元素(element)-数组中的每一个元素都有一...

数组和对象方法&amp;数组去重 数组去重的5种方法前端

列举一下JavaScript数组和对象有哪些原生方法?数组:arr.concat(arr1,arr2,arrn);--合并两个或多个数组。此方法不会修改原有数组,而是返回一个新数组...

C++ 类如何定义对象数组?初始化数组?linux C++第43讲

对象数组学过C语言的读者对数组的概念应该很熟悉了。数组的元素可以是int类型的变量,例如int...

ElasticSearch第六篇:复合数据类型-数组,对象

在ElasticSearch中,使用JSON结构来存储数据,一个Key/Value对是JSON的一个字段,而Value可以是基础数据类型,也可以是数组,文档(也叫对象),或文档数组,因此,每个JSON...

第58条:区分数组对象和类数组对象

示例设想有两个不同类的API。第一个是位向量:有序的位集合varbits=newBitVector;bits.enable(4);bits.enable([1,3,8,17]);b...

八皇后问题解法(Common Lisp实现)

如何才能在一张国际象棋的棋盘上摆上八个皇后而不致使她们互相威胁呢?这个著名的问题可以方便地通过一种树搜索方法来解决。首先,我们需要写一个函数来判断棋盘上的两个皇后是否互相威协。在国际象棋中,皇后可以沿...

visual lisp修改颜色的模板函数 怎么更改visual studio的配色

(defunBF-yansemokuai(tuyuanyanse/ss)...

用中望CAD加载LISP程序技巧 中望cad2015怎么加载燕秀

1、首先请加载lisp程序,加载方法如下:在菜单栏选择工具——加载应用程序——添加,选择lisp程序然后加载,然后选择添加到启动组。2、然后是添加自定义栏以及图标,方法如下(以...

图的深度优先搜索和广度优先搜索(Common Lisp实现)

为了便于描述,本文中的图指的是下图所示的无向图。搜索指:搜索从S到F的一条路径。若存在,则以表的形式返回路径;若不存在,则返回nil。...

两个有助于理解Common Lisp宏的例子

在Lisp中,函数和数据具有相同的形式。这是Lisp语言的一个重大特色。一个Lisp函数可以分析另一个Lisp函数;甚至可以和另一个Lisp函数组成一个整体,并加以利用。Lisp的宏,是实现上述特色的...