对Spring IOC容器相关整理(一)


1.IOC 控制反转(Inversion of Control)

控制反转是一种设计原则,用来降低代码之间的耦合性。其中最常见的方式叫做依赖注入(DI)通过控制反转,对象在被创建的时候,系统内所有对象将通过配置文件(XML,JavaCode,注解等...)配置的依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

容器(Container)容器的作用就是生成(生命周期开始时)、存放bean的实例并控制每个bean实例的生命周期 ,在适当的时候销毁bean实例(生命周期结束时)。

Spring框架支持六个作用域,其中四个只有在使用Web感知的ApplicationContext时才可用。也可以创建自定义范围。

作用域

描述

singleton(单例)

(默认)SpringIoC容器为每个bean定义只创建一个对象实例

prototype(原型)

每次调用都将创建对象实例。

request(请求)

每次HTTP请求都会创建自己的bean实例。仅仅使用Web感知的ApplicationContext时才可用。

session(会话)

每个会话都会创建自己的bean实例。仅仅使用Web感知的ApplicationContext时才可用。

application(应用)

在ServletContext的生命周期中使用单个bean定义. 仅仅使用Web感知的ApplicationContext时才可用。

Websocket(Websocket)

将单个bean定义作用于WebSocket的生命周期。仅仅使用Web感知的ApplicationContext时才可用。

IoC模式中,系统通过引入实现了IoC模式的IoC容器,即可由IoC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分离。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。

可以把IoC模式看作工厂模式的升华,把IoC容器看作是一个大工厂,只不过这个大工厂里要生成的对象都是在配置文件(XML,JavaCode,注解等...)中给出定义的。利用Java 的“反射”编程,根据配置文件(XML,JavaCode,注解等...)中给出的类定义生成相应的对象。从实现来看,以前在工厂模式里写死了的对象,IoC模式改为配置文件(XML,JavaCode,注解等...),这就把工厂和要生成的对象两者隔离,极大提高了灵活性和可维护性

1.1、BeanFactory

org.springframework.beans org.springframework.context 包是Spring 框架IOC容器的基础。BeanFactory 接口提供了一种高级配置机制,能够管理任何类型的对象。ApplicationContext BeanFactory的子接口。

BeanFacotry是spring中比较原始的Factory。如XMLBeanFactory就是一种典型的BeanFactory。原始的BeanFactory无法支持spring的许多插件,如AOP功能、Web应用等。 
ApplicationContext接口,它由BeanFactory接口派生而来,ApplicationContext包含BeanFactory的所有功能,通常建议优先使用ApplicationContext

1 Resource resource = new FileSystemResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
1 ClassPathResource resource = new ClassPathResource("beans.xml");
2 BeanFactory factory = new XmlBeanFactory(resource);
1 ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"applicationContext.xml", "applicationContext-part2.xml"});
3 BeanFactory factory = (BeanFactory) context;

BeanFacotry 提供了六种方法供用户调用

  •   boolean containsBean(String beanName) 判断工厂中是否包含给定名称的bean定义,若有则返回true
  •   Object getBean(String) 返回给定名称注册的bean实例。根据bean的配置情况,如果是singleton模式将返回一个共享实例,否则将返回一个新建的实例,如果没有找到指定bean,该方法可能会抛出异常
  •   Object getBean(String, Class) 返回以给定名称注册的bean实例,并转换为给定class类型
  •   Class getType(String name) 返回给定名称的bean的Class,如果没有找到指定的bean实例,则抛出NoSuchBeanDefinitionException异常
  •   boolean isSingleton(String) 判断给定名称的bean定义是否为单例模式
  •   String[] getAliases(String name) 返回给定bean名称的所有别名

参考:

1.2、ApplicationContext

org.springframework.context.ApplicationContext接口表示SpringIoC容器,负责实例化、配置和组装bean BeanFactory 提供了配置框架和基本功能,ApplicationContext 添加了更多特定于企业的功能。ApplicationContext 是一个完整的BeanFactory 的扩展集

ApplicationContext 的实现类有FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。

ClassPathXmlApplicationContext 默认从类路径加载配置文件,FileSystemXmlApplicationContext 默认从文件系统中装载配置文件

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

ApplicationContext ctx = new ClassPathXmlApplicationContext(“com/baobaotao/context/beans.xml”)

对于ClassPathXmlApplicationContext来说,”com/baobaotao/context/beans.xml”等同于”classpath: com/baobaotao/context/beans.xml”。

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

ApplicationContext ctx =new FileSystemXmlApplicationContext(“com/baobaotao/context/beans.xml”);  

对于FileSystemXmlApplicationContext来说,“com/baobaotao/context/beans.xml”等同于“file:com/baobaotao/context/beans.xml”。

还可以指定一组配置文件,Spring会自动将多个配置文件在内存中”整合”成一个配置文件,如下所示:

ApplicationContext ctx = new ClassPathXmlApplicationContext(new String[]{“conf/beans1.xml”,”conf/beans2.xml”});

ApplicationContext的初始化和BeanFactory有一个重大的区别:BeanFactory在初始化容器时,并未实例化Bean,直到第一次访问某个Bean时才实例目标Bean;而ApplicationContext则在初始化应用上下文时就实例化所有单实例的Bean。因此ApplicationContext的初始化时间会比BeanFactory稍长一些,不过稍后的调用则没有”第一次惩罚”的问题。

1.3、WebApplicationContext

WebApplicationContext  继承了ApplicationContext接口,是ApplicationContext的扩展,它增加了WEB应用特性,还可以视图解析、主题解析、映射,通过ServletContext与servlet关联 ,WebApplicationContext被绑定在ServletContext上(通过ContextLoaderListener绑定),可以通过RequestContextUtils获取WebApplicationContext。

WebApplicationContext是专门为web应用准备的,他允许从相对于web根目录的路劲中装载配置文件完成初始化工作,从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便web应用可以访问spring上下文,spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法来获得WebApplicationContext对象

WebApplicationContext扩展了ApplicationContext.在 WebApplicationContext中定义了一个常量 ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,在上下文启动时,WebApplicationContext以此为键放置在ServletContext属性列表中,

public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
        return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
    }

ConfigurableWebApplicationContext扩展了WebApplicationContext,它允许通过配置的方式实例化,同时设置两个重要方法

  setServletContext(ServletContext context) 为spring设置web应用上下文,以便两者整合

setConfigLocations(String[]locations) 设置Spring配置的文件地址

webApplicationContext初始化需要ServletContext,也就是说需要web容器前提下才能·完成启动工作  可以通过在web.xml中配置自启动Servlet或Web容器监听来实现web容器的启动

Spring分别提供启动WebApplicationContext的servlet和Web容器监听器

  org.springframework.web.context.ContextLoaderListener  

 org.springframework.web.context.ContexLoaderServlet     此方法目前以废弃

!--从类路径下加载Spring配置文件,classpath特指类路径下加载-->
    
        contextConfigLocation
        
            classpath:smart-context.xml
        
    
    
    
        class>org.springframework.web.context.ContextLoaderListenerclass>
    

如果使用@Configuration的java类提供配置信息的配置  web.xml配置修改如下


    
        contextClass
        
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        
    

    
        contextConfigLocation
        com.example.Car,com.example.Boss
    
    
    
        class>org.springframework.web.context.ContextLoaderListenerclass>
    

参考:

1.4 配置元数据

SpringIoC容器使用一种配置元数据。此配置元数据展示了Spring 容器如何在应用程序中实例化、配置和组装对象。

Spring容器支持基于XML的配置元数据配置,Spring2.5引入了对基于注释的配置元数据的支持Spring3.0开始,Spring JavaConfig 项目提供的许多特性成为核心Spring框架的一部分,引入了对基于Java的配置元数据的支持

基于XML的配置元数据将这些bean配置为在顶层元素内部的元素。Java配置通常在带有@Configuration注释的类中使用带@Bean注释的方法。

 基于XML的配置元数据的基本结构:

<?xml version="1.0" encoding="UTF-8"?>
//www.springframework.org/schema/beans/spring-beans.xsd">

class="..."> ① ②

<!-这个bean的协作者(引用其他的bean)和配置在这里->

class="...">

<!-这个bean的协作者和配置在这里->


<!-更多的bean配置在这里->

id属性是标识单个bean定义的字符串,class属性定义Bean的类型,并使用完全限定的类名称。

基于Java的配置元数据的基本结构:

@Configuration  
public class SpringConfig {  
  
    @Bean  
    public Piano piano(){  
        return new Piano();  
    }  
    @Bean(name = "counter")   
    public Counter counter(){  
        return  new Counter(12,"Shake it Off",piano());  
    }  
}