Spring-ApplicationContext解读

简介: Spring-ApplicationContext解读

BeanFactory和ApplicationContext

Spring通过一个配置文件描述Bean和Bean之间的依赖关系,利用Java反射功能实例化Bean,并建立Bean之间的依赖关系。

Spring的IOC容器在完成这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代理、时间发布、资源装载等高级服务。

BeanFactory是Spring框架最核心的接口,它提供了高级IOC的配置机制。

ApplicationContext建立在BeanFactory的基础上,提供了更多面向应用的功能, 它提供了国际化支持和框架事件体系。

我们一般称BeanFactory为IoC容器,而称ApplicationContext为应用上下文,但有时候为了行文方便,我们也将ApplicationContext称为Spring容器。

对于BeanFactory 和 ApplicationContext的用途:

  • BeanFactory是Spring框架的基础设施,面向Spring本身
  • ApplicationContext面向使用Spring框架的开发者,几乎所有的应用场合都可以直接使用Application而非底层的BeanFactory.

ApplicationContext

ApplicationContext概述

Application由BeanFactory派生而来,提供了更多面向实际的功能。

在BeanFactory中,很多功能都需要以编程的形式实现,但是在Application中则可以通过配置的方式实现。


ApplicationContext类体系结构

Application继承了HierachicalBeanFactory和ListableBeanFactory接口,在此基础上,还通过其他接口扩展了BeanFactory的功能。

这些接口如下:

  • ApplicationEventPublisher:让容器拥有发布应用上下文事件的功能,包括容器的启动事件、关闭事件等。
  • MessageSource:为应用提供i18N国际化消息访问的功能
  • ResourcePatternResolver:加载资源,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件
  • LifeCycle:该接口提供start()和stop()方法,主要用于控制异步处理的过程,以达到管理和控制JMX、任务调度等目的

ConfigurableApplicationContext扩展于ApplicationContext,主要新增了两个方法 refresh()和close(),让Application具有启动、刷新、关闭应用上下文的能力。

在应用上下文关闭的情况下,refresh可以启动上下文,在启动的情况下可以清楚缓存并重新装载配置信息。 close方法这可以关闭上下文。

以上内容了解即可。


ApplicationContext初始化

在获取ApplicationContext实例后,我们就可以像BeanFactory那样调用getBean(beanName)返回Bean了。

ApplicationContext的初始化和BeanFactory初始化有一个重大区别:

BeanFactory在初始化容器时,并没有实例化Bean,直到第一次访问某个Bean时才实例化目标Bean。

ApplicationContext会在初始化应用上下文时就实例化所有单实例的Bean。

因此,ApplicationContext的初始化时间会比BeanFactory的时间稍微长一些,不过稍后的调用则没有“第一次惩罚”的问题。


ApplicationContext两个主要实现类

  • ClassPathXmlApplicationContext
  • FileSystemXmlApplicationContext

Plane.java和bean-plane.xml请参考

http://blog.csdn.net/yangshangwei/article/details/74910935#t3

ClassPathXmlApplicationContext

package com.xgj.master.ioc.beanfactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ClassPathXmlApplicationTest {
  public static void main(String[] args) {
    ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
      "classpath:com/xgj/master/ioc/beanfactory/bean-plane.xml");
    Plane plane = (Plane) applicationContext.getBean("plane");
    plane.introduce();
  }
}

如果配置文件放在在类路径下,则优先考虑使用ClassPathXmlApplication实现类

对于 ClassPathXmlApplicationContext 来讲:

new ClassPathXmlApplicationContext(
      "classpath:com/xgj/master/ioc/beanfactory/bean-plane.xml");

等同于

new ClassPathXmlApplicationContext(
      "com/xgj/master/ioc/beanfactory/bean-plane.xml");

FileSystemXmlApplicationContext

package com.xgj.master.ioc.beanfactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class FileSystemXmlApplicationTest {
  public static void main(String[] args) {
    ApplicationContext app = new FileSystemXmlApplicationContext(
        "file:D:/workspace/workspace-jee/HelloSpring/Spring4-char2/src/com/xgj/master/ioc/beanfactory/bean-plane.xml");
    Plane plane = (Plane) app.getBean("plane");
    plane.introduce();
  }
}

如果配置文件放在文件系统路径下,则优先考虑使用FileSystemXmlApplication实现类

对于FileSystemXmlApplication来讲,

"file:D:/workspace/workspace-jee/HelloSpring/Spring4-char2/src/com/xgj/master/ioc/beanfactory/bean-plane.xml"

等同于

"D:/workspace/workspace-jee/HelloSpring/Spring4-char2/src/com/xgj/master/ioc/beanfactory/bean-plane.xml"

运行结果:


加载一组配置文件

初始化配置文件时,还可以指定一组配置文件,Spring会自动对多个配置文件在内存中“整合”成一个配置文件。

举例:

我们新增一个Car类,和Plane中的属性方法一致,增加一个配置文件bean-car.xml,和bean-plane.xml中的结构一致。


ClassPathXmlApplicationContext加载一组资源文件

//两种写法  
ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[] {
        "com/xgj/master/ioc/beanfactory/bean-plane.xml", "com/xgj/master/ioc/beanfactory/bean-car.xml" });
ApplicationContext ctx2 = new ClassPathXmlApplicationContext(
        "com/xgj/master/ioc/beanfactory/bean-plane.xml", "com/xgj/master/ioc/beanfactory/bean-car.xml");
Plane plane2 = (Plane) ctx2.getBean("plane");
Car car = (Car) ctx2.getBean("car");
plane2.introduce();
car.introduce();

FileSystemXmlApplicationContext加载一组资源文件

// 加载多组资源文件
ApplicationContext ctx = new FileSystemXmlApplicationContext(
        "file:D:/workspace/workspace-jee/HelloSpring/Spring4-char2/src/com/xgj/master/ioc/beanfactory/bean-plane.xml",
        "file:D:/workspace/workspace-jee/HelloSpring/Spring4-char2/src/com/xgj/master/ioc/beanfactory/bean-car.xml");
Plane plane2 = (Plane) ctx.getBean("plane");
Car car = (Car) ctx.getBean("car");
plane2.introduce();
car.introduce();

运行结果:


基于类注解的配置方式

Spring支持基于类注解的配置方式,主要来源于Spring的子项目JavaConfig。 目前JavaConfig已经成为Spring核心框架的一部分。

这里只是简单的演示用法,后续更新详情。

一个标注了@Configuration注解的POJO即可提供Spring所需要的配置信息。

代码如下:

Beans.java 配置信息提供类

package com.xgj.spring4.chapter4.configuration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // @Configuration表示是一个配置信息提供类
public class Beans {
  @Bean(name = "plane") // ͨ定义一个Bean,通过name指定bean的名称
  public Plane createPlane() {
    Plane plane = new Plane();
    plane.setBrand("F35");
    plane.setColor("GREY");
    plane.setMaxSpeed(800);
    return plane;
  }
}

Plane.java

package com.xgj.spring4.chapter4.configuration;
public class Plane {
  private String brand;
  private String color;
  private int maxSpeed;
  ...
  省略setter/getter方法
  public void introduce(){
    System.out.println("Plane brand:" + brand + " ,Color:" + color + ",maxSpeed:" + maxSpeed);
  }
}

AnnotationConfigApplicationTest.java 测试:

package com.xgj.spring4.chapter4.configuration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class AnnotationConfigApplicationTest {
  public static void main(String[] args) {
    // ͨ通过一个带有@Configuration的POJO装载Bean的配置
    ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class);
    Plane plane = ctx.getBean("plane", Plane.class);
    plane.introduce();
  }
}

运行结果:

解析:

Spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplication。

AnnnotationConfigApplication将加载Beans.class中的Bean定义并调用Beans.class中的方法实例化Bean,启动并装载Bean。


Spring4支持Groovy DSL配置Bean

Spring4.0支持使用Groovy DSL来进行Bean的定义, 与XML文件的配置类似,只不过基于Groovy脚本语言,可以实现更加负载灵活的Bean的配置逻辑。

步骤:

  • 添加依赖包
<dependency>
      <groupId>org.codehaus.groovy</groupId>
      <artifactId>groovy-all</artifactId>
      <version>2.3.6</version>
    </dependency>
  • 编写代码
    groovy-bean.groovy 配置信息
package com.xgj.spring4.chapter4.groovy;
beans{
  plane(Plane){
    brand = "A380";
    color = "red";
    maxSpeed = 700;
  }
}

Plane同上。

测试类:

package com.xgj.spring4.chapter4.groovy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericGroovyApplicationContext;
public class GroovyApplicationContextTest {
  public static void main(String[] args) {
    // TODO Auto-generated method stub
    ApplicationContext ctx = new GenericGroovyApplicationContext("classpath:com/xgj/spring4/chapter4/groovy/groovy-bean.groovy");
    Plane plane = (Plane)ctx.getBean("plane");
    plane.introduce();
  }
}

基于Groovy的配置方式很容易让开发者配置负载Bean的实例化过程,比基于XML文件、注解的配置方式更加灵活。

Spring为依据Groovy的配置提供了专门的Application实现类:GenericiGroovyApplicationContext.

相关文章
|
XML 存储 JSON
如何快速实现XML与JSON转换
XML与JSON之间的转换常常用于以下场景: 1.数据交换:当需要在不同的系统、平台或服务之间进行数据交换时,常常会使用XML或JSON进行数据的序列化和反序列化。比如,一个Web服务可能需要返回数据给一个移动应用,这时,数据就可以通过XML或JSON格式进行传输。
|
C# iOS开发 MacOS
MacOS操作系统当中运行VSCode并配置运行调试C#项目
在开发的过程当中,经常会遇到各种开发环境,在MacOS上如何运行VSCode,配置并且调试C#项目,本文进行讲解
2748 0
MacOS操作系统当中运行VSCode并配置运行调试C#项目
|
存储 安全 Java
发现 XSS 漏洞?别急!SpringBoot这招轻松搞定!
在SpringBoot中,发现XSS(跨站脚本)漏洞时,可以通过一系列措施来轻松搞定这些安全问题。XSS攻击允许攻击者在受害者的浏览器中注入恶意脚本,这些脚本可以窃取用户的敏感信息、劫持用户会话或进行其他恶意操作。以下是一些在SpringBoot中修复XSS漏洞的有效方法
2004 7
|
7月前
|
人工智能 缓存 搜索推荐
大模型应用联网搜索:重塑智能时代的交互与决策
本文将从这一核心问题出发,解析大模型应用联网搜索的颠覆性价值,剖析其如何解决传统模型的局限。
589 21
|
Prometheus 监控 Cloud Native
【监控】prometheus传统环境监控告警常用配置
【监控】prometheus传统环境监控告警常用配置
【监控】prometheus传统环境监控告警常用配置
|
存储 Cloud Native 关系型数据库
PolarDB 高可用架构设计与实践
【8月更文第27天】 在现代互联网应用中,数据库作为核心的数据存储层,其稳定性和可靠性尤为重要。阿里云的 PolarDB 作为一款云原生的关系型数据库服务,提供了高可用、高性能和自动化的特性,适用于各种规模的应用。本文将详细介绍 PolarDB 的高可用架构设计,并探讨其实现数据安全性和业务连续性的关键技术。
389 0
|
监控 Dubbo 搜索推荐
No application config found or it‘s not a valid config! Please add <dubbo:application name=“...“ />
No application config found or it‘s not a valid config! Please add <dubbo:application name=“...“ />
1651 1
|
8月前
|
Rust 前端开发 算法
java中如何实现单链表反转
本文介绍了单向链表的创建及其反转的三种实现方法。首先,通过`DataNode`类构建了一个包含10个节点的单向链表,并提供了链表的打印功能。接着,分别使用递归、遍历和借助栈的方式实现了链表反转。递归方法简单但受限于栈深度(最大约12000个节点),遍历方法通用且效率最高,而借助栈的方法虽然易于理解但效率较低。通过对不同方法的时间性能测试,得出遍历方式在处理大规模数据时表现最佳。
328 1
|
XML Java 程序员
Spring6框架中依赖注入的多种方式(推荐构造器注入)
依赖注入(DI)是一种过程,对象通过构造函数参数、工厂方法的参数或在对象实例构建后设置的属性来定义它们的依赖关系(即与其一起工作的其他对象)。
460 3
|
XML JavaScript Java
BeanFactory 和 FactoryBean的区别
本文介绍了Spring框架中的`BeanFactory`和`FactoryBean`。`BeanFactory`是Spring的核心接口,用于管理Bean的创建、配置及依赖注入。其实现包括`DefaultListableBeanFactory`和已废弃的`XmlBeanFactory`。`FactoryBean`则用于动态创建Bean实例,支持懒加载及AOP代理创建。文章还通过示例展示了如何实现一个`FactoryBean`,并通过测试验证其功能。最后附上了作者信息及版权声明。
442 0
BeanFactory 和 FactoryBean的区别