Spring框架-IOC容器和Bean的配置(1)

来源:互联网 发布:善软件 小众 编辑:程序博客网 时间:2024/06/06 18:14

1IOC和DI

①IOC(Inversion of Control):反转控制

在应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取所需要的资源,在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效率。

反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。

②DI(Dependency Injection):依赖注入

IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。

③IOC容器在Spring中的实现

[1]在通过IOC容器读取Bean的实例之前,需要先将IOC容器本身实例化。

[2]Spring提供了IOC容器的两种实现方式

(1)BeanFactory:IOC容器的基本实现,是Spring内部的基础设施,是面向Spring本身的,不是提供给开发人员使用的。

(2)ApplicationContext:BeanFactory的子接口,提供了更多高级特性。面向Spring的使用者,几乎所有场合都使用ApplicationContext而不是底层的BeanFactory。

Spring框架-IOC容器和Bean的配置(1)

ApplicationContext的主要实现类

[1]ClassPathXmlApplicationContext:对应类路径下的XML格式的配置文件

[2]FileSystemXmlApplicationContext:对应文件系统中的XML格式的配置文件

[3]在初始化时就创建单例的bean,也可以通过配置的方式指定创建的Bean是多实例的。

⑤ConfigurableApplicationContext

[1]是ApplicationContext的子接口,包含一些扩展方法

[2]refresh()和close()让ApplicationContext具有启动、关闭和刷新上下文的能力。

⑥WebApplicationContext

专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作

1通过类型获取bean

从IOC容器中获取bean时,除了通过id值获取,还可以通过bean的类型获取。但如果同一个类型的bean在XML文件中配置了多个,则获取时会抛出异常,所以同一个类型的bean在容器中必须是唯一的。

HelloWorld helloWorld = cxt.getBean(HelloWorld.class);

2给bean的属性赋值

2.1赋值的途经

①通过bean的setXxx()方法赋值

HelloWorld中使用的就是这种方式

Spring框架-IOC容器和Bean的配置(1)

②通过bean的构造器赋值

<beanid="book"class="com.atguigu.spring.bean.Book">

<constructor-argvalue="10010"/>

<constructor-argvalue="Book01"/>

<constructor-argvalue="Author01"/>

<constructor-argvalue="20.2"/>

</bean>

<beanid="book"class="com.atguigu.spring.bean.Book">

<constructor-argvalue="10010"/>

<constructor-argvalue="Book01"/>

<constructor-argvalue="Author01"/>

<constructor-argvalue="20.2"/>

</bean>

●通过索引值指定参数位置

<beanid="book"class="com.atguigu.spring.bean.Book">

<constructor-argvalue="10010"index="0"/>

<constructor-argvalue="Book01"index="1"/>

<constructor-argvalue="Author01"index="2"/>

<constructor-argvalue="20.2"index="3"/>

</bean>

●通过类型不同区分重载的构造器

<beanid="book"class="com.atguigu.spring.bean.Book">

<constructor-argvalue="10010"index="0"type="java.lang.Integer"/>

<constructor-argvalue="Book01"index="1"type="java.lang.String"/>

<constructor-argvalue="Author01"index="2"type="java.lang.String"/>

<constructor-argvalue="20.2"index="3"type="java.lang.Double"/>

</bean>

③给bean的级联属性赋值

<bean id="action" class="com.atguigu.spring.ref.Action">

<property name="service" ref="service"/>

<!-- 设置级联属性(了解) -->

<property name="service.dao.dataSource" value="DBCP"/>

</bean>

④p名称空间

为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。

Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean的属性。

使用p命名空间后,基于XML的配置方式将进一步简化。

<bean

id="studentSuper"

class="com.atguigu.helloworld.bean.Student"

p:studentId="2002" p:stuName="Jerry2016" p:age="18" />

1.1可以使用的值

①字面量

[1]可以使用字符串表示的值,可以通过value属性或value子节点的方式指定

[2]基本数据类型及其封装类、String等类型都可以采取字面值注入的方式

[3]若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来

②null值

<beanclass="com.atguigu.spring.bean.Book"id="bookNull">

<propertyname="bookId"value="2000"/>

<propertyname="bookName">

<null/>

</property>

<propertyname="author"value="nullAuthor"/>

<propertyname="price"value="50"/>

</bean>

③外部已声明的bean

<beanid="shop"class="com.atguigu.spring.bean.Shop">

<propertyname="book"ref="book"/>

</bean>

④内部bean

当bean实例仅仅给一个特定的属性使用时,可以将其声明为内部bean。内部bean声明直接包含在<property>或<constructor-arg>元素里,不需要设置任何id或name属性

内部bean不能使用在任何其他地方

<beanid="shop2"class="com.atguigu.spring.bean.Shop">

<propertyname="book">

<beanclass="com.atguigu.spring.bean.Book">

<propertyname="bookId"value="1000"/>

<propertyname="bookName"value="innerBook"/>

<propertyname="author"value="innerAuthor"/>

<propertyname="price"value="50"/>

</bean>

</property>

</bean>

1.1集合属性

在Spring中可以通过一组内置的XML标签来配置集合属性,例如:<list>,<set>或<map>。

①数组和List

配置java.util.List类型的属性,需要指定<list>标签,在标签里包含一些元素。这些标签可以通过<value>指定简单的常量值,通过<ref>指定对其他Bean的引用。通过<bean>指定内置bean定义。通过<null/>指定空元素。甚至可以内嵌其他集合。

数组的定义和List一样,都使用<list>元素。

配置java.util.Set需要使用<set>标签,定义的方法与List一样。

<beanid="shop"class="com.atguigu.spring.bean.Shop">

<propertyname="categoryList">

<!-- 以字面量为值的List集合 -->

<list>

<value>历史</value>

<value>军事</value>

</list>

</property>

<propertyname="bookList">

<!-- 以bean的引用为值的List集合 -->

<list>

<refbean="book01"/>

<refbean="book02"/>

</list>

</property>

</bean>

②Map

Java.util.Map通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签。每个条目包含一个键和一个值。

必须在<key>标签里定义键。

因为键和值的类型没有限制,所以可以自由地为它们指定<value>、<ref>、<bean>或<null/>元素。

可以将Map的键和值作为<entry>的属性定义:简单常量使用key和value来定义;bean引用通过key-ref和value-ref属性定义。

<bean id="cup" class="com.atguigu.spring.bean.Cup">

<property name="bookMap">

<map>

<entry>

<key>

<value>bookKey01</value>

</key>

<ref bean="book01"/>

</entry>

<entry>

<key>

<value>bookKey02</value>

</key>

<ref bean="book02"/>

</entry>

</map>

</property>

</bean>

③Properties

使用<props>定义java.util.Properties,该标签使用多个<prop>作为子标签。每

个<prop>标签必须定义key属性

<bean class="com.atguigu.spring.bean.DataSource" id="dataSource">

<property name="properties">

<props>

<prop key="userName">root</prop>

<prop key="password">root</prop>

<prop key="url">jdbc:mysql:///test</prop>

<prop key="driverClass">com.mysql.jdbc.Driver</prop>

</props>

</property>

</bean>

④集合类型的bean

如果只能将集合对象配置在某个bean内部,则这个集合的配置将不能重用。我们需要将集合bean的配置拿到外面,供其他bean引用。

配置集合类型的bean需要引入util名称空间

<util:list id="bookList">

<ref bean="book01"/>

<ref bean="book02"/>

<ref bean="book03"/>

<ref bean="book04"/>

<ref bean="book05"/>

</util:list>

<util:list id="categoryList">

<value>编程</value>

<value>极客</value>

<value>相声</value>

<value>评书</value>

</util:list>

1通过工厂创建bean

1.1静态工厂

调用静态工厂方法创建bean是将对象创建的过程封装到静态方法中。当客户端需要对象时,只需要简单地调用静态方法,而不用关心创建对象的细节。

声明通过静态方法创建的bean需要在bean的class属性里指定静态工厂类的全类名,同时在factory-method属性里指定工厂方法的名称。最后使用<constrctor-arg>元素为该方法传递方法参数。

1.2实例工厂

实例工厂方法:将对象的创建过程封装到另外一个对象实例的方法里。当客户端需要请求对象时,只需要简单的调用该实例方法而不需要关心对象的创建细节。

实现方式

①配置工厂类实例的bean

②在factory-method属性里指定该工厂方法的名称

③使用 construtor-arg 元素为工厂方法传递方法参数

1.1FactoryBean

Spring中有两种类型的bean,一种是普通bean,另一种是工厂bean,即FactoryBean。

工厂bean跟普通bean不同,其返回的对象不是指定类的一个实例,其返回的是该工厂bean的getObject方法所返回的对象。

工厂bean必须实现org.springframework.beans.factory.FactoryBean接口。

Spring框架-IOC容器和Bean的配置(1)

<bean id="product" class="com.atguigu.spring.bean.ProductFactory">

<property name="productName" value="Mp3" />

</bean>

1bean的高级配置

1.1配置信息的继承

①背景

查看下面两个Employee的配置,其中dept属性是重复的。

<bean id="dept" class="com.atguigu.parent.bean.Department">

<property name="deptId" value="100"/>

<property name="deptName" value="IT"/>

</bean>

<bean id="emp01" class="com.atguigu.parent.bean.Employee">

<property name="empId" value="1001"/>

<property name="empName" value="Tom"/>

<property name="age" value="20"/>

<!-- 重复的属性值 -->

<property name="detp" ref="dept"/>

</bean>

<bean id="emp02" class="com.atguigu.parent.bean.Employee">

<property name="empId" value="1002"/>

<property name="empName" value="Jerry"/>

<property name="age" value="25"/>

<!-- 重复的属性值 -->

<property name="detp" ref="dept"/>

</bean>

②配置信息的继承

<!-- 以emp01作为父bean,继承后可以省略公共属性值的配置 -->

<bean id="emp02" parent="emp01">

<property name="empId" value="1002"/>

<property name="empName" value="Jerry"/>

<property name="age" value="25"/>

</bean>

Spring允许继承bean的配置,被继承的bean称为父bean。继承这个父bean的bean称为子bean

子bean从父bean中继承配置,包括bean的属性配置

子bean也可以覆盖从父bean继承过来的配置

③补充说明

父bean可以作为配置模板,也可以作为bean实例。若只想把父bean作为模板,可以设置<bean>的abstract 属性为true,这样Spring将不会实例化这个bean

如果一个bean的class属性没有指定,则必须是抽象bean

并不是<bean>元素里的所有属性都会被继承。比如:autowire,abstract等。

也可以忽略父bean的class属性,让子bean指定自己的类,而共享相同的属性配置。但此时abstract必须设为true。

1.1bean之间的依赖

有的时候创建一个bean的时候需要保证另外一个bean也被创建,这时我们称前面的bean对后面的bean有依赖。例如:要求创建Employee对象的时候必须创建Department。这里需要注意的是依赖关系不等于引用关系,Employee即使依赖Department也可以不引用它。

<bean id="emp03" class="com.atguigu.parent.bean.Employee" depends-on="dept">

<property name="empId" value="1003"/>

<property name="empName" value="Kate"/>

<property name="age" value="21"/>

</bean>

1.2bean的作用域

在Spring中,可以在<bean>元素的scope属性里设置bean的作用域,以决定这个bean是单实例的还是多实例的。

默认情况下,Spring只为每个在IOC容器里声明的bean创建唯一一个实例,整个IOC容器范围内都能共享该实例:所有后续的getBean()调用和bean引用都将返回这个唯一的bean实例。该作用域被称为singleton,它是所有bean的默认作用域。

Spring框架-IOC容器和Bean的配置(1)

当bean的作用域为单例时,Spring会在IOC容器对象创建时就创建bean的对象实例。而当bean的作用域为prototype时,IOC容器在获取bean的实例时创建bean的实例对象。

1.1bean的生命周期

①Spring IOC容器可以管理bean的生命周期,Spring允许在bean生命周期内特定的时间点执行指定的任务。

②Spring IOC容器对bean的生命周期进行管理的过程:

[1]通过构造器或工厂方法创建bean实例

[2]为bean的属性设置值和对其他bean的引用

[3]调用bean的初始化方法

[4]bean可以使用了

[5]当容器关闭时,调用bean的销毁方法

③在配置bean时,通过init-method和destroy-method 属性为bean指定初始化和销毁方法

④bean的后置处理器

[1]bean后置处理器允许在调用初始化方法前后对bean进行额外的处理

[2]bean后置处理器对IOC容器里的所有bean实例逐一处理,而非单一实例。其典型应用是:检查bean属性的正确性或根据特定的标准更改bean的属性。

[3] bean后置处理器时需要实现接口:org.springframework.beans.factory.config.BeanPostProcessor。在初始化方法被调用前后,Spring将把每个bean实例分别传递给上述接口的以下两个方法:

●postProcessBeforeInitialization(Object, String)

●postProcessAfterInitialization(Object, String)

⑤添加bean后置处理器后bean的生命周期

[1]通过构造器或工厂方法创建bean实例

[2]为bean的属性设置值和对其他bean的引用

[3]将bean实例传递给bean后置处理器的postProcessBeforeInitialization()方法

[4]调用bean的初始化方法

[5]将bean实例传递给bean后置处理器的postProcessAfterInitialization()方法

[6]bean可以使用了

[7]当容器关闭时调用bean的销毁方法

后续5.5

引用外部属性文件

0 0
原创粉丝点击