Spring 4.x IOC介绍(二.BeanFactory 、ApplicationContext、WebApplicationContext之ApplicationContext)

18 篇文章 0 订阅

ApplicationContext介绍

如果说BeanFactory是Spring的“心脏”,那么ApplicationContext就是完整的“身躯”了。ApplicationContextBeanFactory派生而来,提供了更多面向实际应用的功能,在BeanFactory中,很多功能需要以编程的方式实现,而在ApplicationContext中则可以通过配置的方式实现。

ApplicationContext的体系结构

ApplicationContext的主要实现类是ClassPathXmlApplicationContextFileSystemXmlApplicationContext,前者默认从类路径加载配置文件,后者默认从文件系统中装载配置文件。下面看一下ApplicationContext的类继承体系,如下图所示:
ApplicationContext的体系结构
ApplicationContext继承了HierarchiacalBeanFactoryListableBeanFactory接口,在此基础上,还通过多个其他的接口扩展了BeanFactory的功能。如:

  • ApplicationEventPublicsher:让容器拥有发布应用上下文事件的功能,包括容器启动事件、关闭事件等。实现了ApplicationListener事件监听接口的Bean可以接收到的容器事件,并对时间进行相应处理。在ApplicationListener事件监听接口的Bean可以接收到容器事件,并对事件进行相应处理。在ApplicationContext抽象实现类AbstractApplicationContext中存在一个ApplicationEventMulticaster,他负责保存所有的监听器,以便在容器产生上下文事件时通过这些事件监听者。
  • MessageSource:为应用提供i18n国际化消息访问的功能。
  • ResourcePatternResolver:所有ApplicationContext实现类都实现了类似于PathMatchingResourcePatternResolver的功能,可以通过带前缀的Ant风格的资源文件路径装载Spring的配置文件。
  • LifeCycle:该接口提供了start()和stop()两个方法,主要用于控制一步处理过程。在具体使用时,该接口同时被ApplicationContext实现及具体Bean实现,ApplicationContext会将start/stop的信息传递给容器中所有实现了该接口的Bean,已达到管理和控制JMX、任务调度等目的。

ConfigurableApplicationContext扩展于ApplicationContext,它新增了两个主要的方法:refresh()和close(),让ApplicationContext具有启动、刷新和关闭应用上下问的能力。在因果那个上下文关闭的情况下调用refresh()则可清楚缓存并重新装载配置信息,而调用close()则可关闭应用上下文。这些接口方法为容器的控制管理带来了便利,但作为开发者,我们并不需要过多关系这些方法。

ApplicationContext初始化

和BeanFactory初始化类似,ApplicationContext的初始化也很简单。如果配置文件放置在类路径下,则可以优先考略使用ClassPathXmlApplicationContext实现类。

ApplicationContext ctx = new ClassPathXMLApplicationContext("resource/spring-config.xml");

对于ClassPathXmlApplicationContext来说,resource/spring-config.xml等同于classpath:resource/spring-config.xml
如果配置文件放置在文件系统的路径下,则可以优先考虑使用FilySystemXmlApplicationContext实现类。

ApplicationContext ctx = new FilySystemXmlApplicationContext("resource/spring-config.xml");

对于FilySystemXmlApplicationContext来说resource/spring-config.xml等同于file:/spring-config.xml
还可以指定一组配置文件,Spring会自动将多个配置文件在内存中“整合”成一个配置文件,如下:

ApplicationContext ctx = new FilySystemXmlApplicationContext(new String[]{"conf/beans1.cml","conf/beans2.cml"});

当然,FileSystemXmlApplicationContext和ClassPathXMLApplication都可以显式使用带资源类型前缀的路径,他们的区别在于如果不显式指定资源类型前缀,则分别将路径解析为文件系统路径和类路径。

在获取ApplicationContext实例后,就可以像BeanFactory一样调用getBean(beanName)返回Bean了。ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,知道第一次访问某个Bean时菜实例化目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有“第一次惩罚”的问题。

Spring支持基于类注解的配置方式,主要工嗯呢该来自Spring的一个名为JavaConfig的子项目。JavaConfig现以升级为Spring核心框架的一部分。一个标注@Configuration注解的POJO即可提供Spring所需的Bean配置信息,如下所示:

import org.springframework.context.annotation.Bean;
import smart.Car;

public class Beans {
    @Bean(name = "car")
    public Car builder(){
        Car car = new Car();
        car.setBrand("Cadillac CT6");
        car.setMaxSpeed(200);
        return car;
    }
}

和基于XML文件的配置相比,类注解的配置方式可以很容易地让开发者控制Bean的初始化过程,比基于XML文件的配置方式更加灵活。
Spring为基于注解类的配置提供了专门的ApplicationContext实现类:AnnotationConfigApplicationContext。看一个使用AnnotationConfigApplicationContext启动Spring容器的实例,如下所示:

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import org.testng.annotations.Test;
import smart.Car;

import static org.testng.Assert.*;
/**
 * @author shengda.ji
 * @date 2018/8/16 下午4:26
 */
public class AnnotationApplicationContextText {
    @Test
    public void getBean(){
        //通过一个带@Configuration的POJO装载Bean配置
        ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class);
        Car car = ctx.getBean("car",Car.class);
        assertNotNull(car);
    }
}

AnnotationConfigApplicationContext将加载Bean.class中的Bean定义并调用Beans.class中的方法实例化Bean,启动容器并装配Bean。
Spring4.0支持使用Groovy脚本语言,可实现复杂、灵活的Bean配置逻辑,来看一个例子:
groovy-beans.groovy

package smart.context;
import smart.Car;

beans{
    car(Car){//①名字(类型)
        brand = "Cadillac CT6"//②注入属性
        maxSpeed = "200"
        color = "red"
    }
}

基于Groovy的配置方式可以很容易地让开发者配置复杂Bean的初始化过程,比基于XML文件、注解的配置方式更灵活。
Spring 为基于Groovy的配置提供了专门的ApplicationContext实现类:Gen。下面看一下如何启动Spring容器的示例:

package smart.context;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericGroovyApplicationContext;
import org.testng.annotations.Test;
import smart.Car;
import static org.testng.Assert.*;

public class GroovyApplicationContextTest {
    @Test
    public void getBean(){
        ApplicationContext ctx = new GenericGroovyApplicationContext("classpath:smart/context/groovy-beans.groovy");
        Car car = (Car)ctx.getBean("car");
        assertNotNull(car);
        assertEquals(car.getColor(),"red");
    }
}

这里会出现两个问题:

  1. 报错:Cannot compile Groovy files: no Groovy library is defined for module ‘xx’
    这个解决的时候需要更改idea的配置:
    !?*.groovy;
    去掉!?*.groovy;就可以解决这个问题。
  2. 更改idea启动后还是报错:java.lang.ClassNotFoundException: groovy.lang.GroovyObject
    添加依赖:
    <dependency> <groupId>org.codehaus.groovy</groupId> <artifactId>groovy-all</artifactId> <version>2.4.7</version> </dependency>

总结:

  • ApplicationContext的主要实现类是ClassPathXMLApplicationContext喝FileSystemXMLApplicationContext
  • ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,知道第一次访问某个Bean时菜实例化目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。
  • xml配置Bean的方式根据本文有三种:
  1. 基于XML的配置;
  2. 基于注解的配置;
  3. 基于groovy配置文件的配置;

这三种各有优缺点,如果Bean的初始化比较复杂,那么groovy是一个很好的选择。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值