Spring核心技术之IoC容器(Version 5.1.3.RELEASE)之一

本文详细介绍了Spring的IoC容器及其核心概念,包括Bean的定义、初始化容器、依赖注入的多种方式(构造器注入、setter注入、依赖解析过程)以及依赖配置细节。文章还探讨了容器的使用,如别名、Bean实例化方法、自动依赖注入的优缺点,以及方法注入中的lookup方法注入和方法替换。通过实例和代码示例,阐述了Spring如何实现控制反转,帮助读者深入理解Spring框架的核心机制。
摘要由CSDN通过智能技术生成

 

目录

Spring Ioc容器和Beans的介绍

容器预览

配置元数据

初始化容器

组合XML描述

Groovy Bean定义DSL

容器使用

Bean命名

BeanDefinition外的Bean别名

Bean实例化

构造器实例化

静态工厂方法实例化

实例工厂方法初始化

依赖

依赖注入

构造器依赖注入

Setter方法依赖注入

依赖解析过程

依赖注入实例

依赖配置细节

直接值(基本类型、String等)

引用其他Bean

内部Bean(Inner Bean)

集合

p命名空间 XML配置

c命名空间XML配置

复合属性

使用depends-on

懒初始化

自动依赖注入

自动注入的局限和缺点

自动注入排除

方法注入

Lookup方法注入

方法替换


Spring Ioc容器和Beans的介绍

 本章将介绍Spring框架对控制反转(IoC)的实现,IoC也叫依赖注入(DI),这是对象借以明确其依赖的手段,具体可以通过构造器参数、工厂方法、属性设置(所设置的对象可以通过构造器或者工厂方法进行创建)。容器在创建Bean时会注入这些依赖,该过程从根本上反转了对象通过构造方法或服务定位方式来实例化其依赖的方式。

 org.springframework.beans 和 org.springframework.context这两个包是Spring IoC容器的基础,BeanFactory接口提供对于任意对象的配置管理功能,ApplicationContext是它的子类,添加了如下功能:

  • 于Spring AOP更容易集成
  •  消息资源处理(用于国际化)
  • 事件发布
  • 应用层具体的上下文,如用于web应用的WebApplicationContext

简单来说,BeanFactory提供了配置框架和基本功能,ApplicationContext则添加更多企业专有功能。

 在Spring中,形成应用支柱及由Spring IoC容器管理的对象被称为beans,一个bean就是由Spring IoC容器实例化、组装并管理的对象,这些Beans以及它们之间的依赖是由Spring容器配置的元数据来映射的。

容器预览

org.springframework.context.ApplicationContext接口代表Spring IoC容器并负责实例化、配置、组装beans。容器通过读取配置元数据来获取对象实例化、配置、组装的说明,元数据存在于XML、Java注解、Java代码中,这些元数据能够描述构成应用的对象及对象之间的相互依赖。

Spring提供了ApplicationContext的一些实现, 在单一功能的应用中,通常利用ClassPathXmlApplicationContext或FileSystemXmlApplicationContext。XML是传统的用来定义元数据的方式,也可以通过Java注解或Java代码的方式来描述元数据配置,并提供一个少量配置的XML文件来指定这些额外的配置。

下图示出了 Spring运行的一个高层视图,应用涉及的class与Spring的配置绑定,当ApplicationContext被创建并初始化后,应用的配置就完成并可以运行了

配置元数据

如上图所示,Spring IoC容器读取配置元数据,这些配置元数据用以告诉Spring IoC容器如何初始化、配置、组装应用中的对象。传统上,主要是通过XML方式来描述这些元数据,本章也主要通过这种方式来传达Spring IoC容器的特点。

 Spring的配置要包括一个或多个需要容器来管理的Bean,XML形式的配置,通过在顶层<beans>元素中通过<bean>来声明这些bean;Java配置方式是在一个具有@Configuration注解的类中通过@Bean注解的方法来声明。

这些Bean定义与应用中的对象相对应,通常而言,主要包括服务层对象、数据访问对象(DAOs)、表现层对象以及Hibernate会话工厂、JMS队列等基础设置对象。通常不需要定义领域对象,其主要是DAOs或者业务逻辑来对这些对象进行创建。

如下为XML配置元数据的一个基础框架

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="..." class="...">   
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <bean id="..." class="...">
        <!-- collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions go here -->

</beans>

其中id属性是用来表示该bean定义的字符串,class属性是表示该bean所描述的对象类型的全限定类名。

初始化容器

ApplicationContext构造器接收代表资源路径的字符串,可以从文件系统、Java类路径等外部资源中加载配置。

ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

如下示出服务层对象的xml配置样例(services.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- services -->

    <bean id="petStore" class="org.springframework.samples.jpetstore.services.PetStoreServiceImpl">
        <property name="accountDao" ref="accountDao"/>
        <property name="itemDao" ref="itemDao"/>
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for services go here -->

</beans>

如下为数据接入层xml配置样例(daos.xml)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="accountDao"
        class="org.springframework.samples.jpetstore.dao.jpa.JpaAccountDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <bean id="itemDao" class="org.springframework.samples.jpetstore.dao.jpa.JpaItemDao">
        <!-- additional collaborators and configuration for this bean go here -->
    </bean>

    <!-- more bean definitions for data access objects go here -->

</beans>

在如上的配置实例中,服务层包括PetStoreServiceImpl类和两个JpaAccountDao、JpaItemDao类型的数据接入层对象,property name元素引用JavaBean的属性名称,ref引用其他的bean定义的名称。id和ref之间的关联表达了协作对象之间的依赖。

组合XML描述

Bean定义跨多个文件情况,通常一个文件描述一个逻辑分层或模块,你可以通过ApplicationContext构造方法把所有的配置文件作为参数传入,如前面所述,该构造方法是可以接受多个资源位置作为参数的。要不然,也可以在XML文件中通过<import>引入其他的文件,如下所示

<beans>
    <import resource="services.xml"/>
    <import resource="resources/messageSource.xml"/>
    <import resource="/resources/themeSource.xml"/>

    <bean id="bean1" class="..."/>
    <bean id="bean2" class="..."/>
</beans>

如上所示,对于外部的Bean定义是从services.xml、messageSource.xml、themeSource.xml这三个文件中加载的,加载的文件路径是相对于当前文件而言的。services.xml文件必须在当前文件相同目录下,而messageSource.xml、themeSource.xml文件则是在当前文件所在目录下的resources目录,需要特别注意的是,路径前的"/"是被忽略掉得。因此,考虑到这些路径都是相对的,最好不要在前面加“/”。被引入的文件必须为满足Spring schema的合法的bean定义文件,包括顶层的<beans>元素。

 通过"../"来引用父目录中的配置文件的方式是不可取的,这种方式将会依赖应用外部的文件。这种方式用在classpath:中也是不可取的,classpath的配置的改变可能会导致引用文件的路径发生相应的改变,进而可能选择了错误的路径和文件。

你可以只使用绝对的路径来引入其他文件,如file:C:/config/services.xmlclasspath:/config/services.xml,不过这种方式会让你的应用与配置的路径有耦合,通常对于这些绝对路径采取间接方式声明,如通过 "${…​}"占位符在系统运行时解析JVM系统属性。

Groovy Bean定义DSL

容器使用

ApplicationContext是用来维护不同beans和bean之间依赖的一个高级工厂,通过T getBean(String name, Class<T> requiredType)你可以获取想要的bean实例,ApplicationContext可以读取bean定义并获取它们

// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");

// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);

// use configured instance
List<String> userList = service.getUsernameList();

如果是Groovy方式的配置,其步骤是相似的,有一个Groovy配置的上下文实现

ApplicationContext context = new GenericGroovyApplicationContext("services.groovy", "daos.groovy");

一个最灵活的方式是通过GenericApplicationContext并结合如XmlBeanDefinitionReader的解析配置的代理

GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();

当然对于Groovy方式的配置也可以通过GroovyBeanDefinitionReader来解析

GenericApplicationContext context = new GenericApplicationContext();
new GroovyBeanDefinitionReader(context).loadBeanDefinitions("services.groovy", "daos.groovy");
context.refresh();

Spring IoC容器用来管理一个或多个Bean,这些Bean通过提供给容器的配置进行创建。在容器内部,这些Bean定义就是BeanDefinition对象,其包括如下元数据:

  • 带包路径的类名:通常是所定义的Bean的具体实现
  • Bean有关配置,主要是该Bean在容器中行为方式(包括Scope、生命周期、回调等)
  • 该Bean所依赖的其它Bean
  • 对于要创建的对象的其它配置,如对于连接池配置的池的大小及连接数目

元数据会转换为BeanDefinition的属性,如下示出相关属性

Property Explained in…​

Class

Instantiating Beans

Name

Naming Beans

Scope

Bean Scopes

Constructor arguments

Dependency Injection

Properties

Dependency Injection

Autowiring mode

Autowiring Collaborators

Lazy initialization mode

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值