二、Spring配置Bean
1.在xml文件中通过Bean节点来配置Bean
<!--通过全类名的方式配置bean-->
<bean id="helloworld" class="com.atguigu.spring.beans.HelloWord">
</bean>
- id:Bean的名称,在IOC 容器中必须是唯一的,若id没有指定,Spring自动将权限定性类名作为Bean的名字,id可以指定多个名字,名字之间可以用逗号、分号、或空格分割。
- class:bean的全类名,通过反射的方式在IOC容器中创建Bean。所以要求Bean中必须有无参数的构造器
2.AppiicationContext
- AppiicationContext的主要实现类:
ClassPathXmlApplicationContext:从类路径下配置文件
FileSystemXmlApplicationContext:从文件体系中加载配置文件 - ConfigurableApplicationContext扩展于ApplicationContext,新增加了两个主要方法refresh()和close(),具有启动、刷新和关闭上下文的能力。
- AppiicationContext在初始化上下文时就实例化所有的单例Bean
- WebAppiicationContext是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作
//1.创建Spring的IOC容器对象
//ApplicationContext 代表IOC容器
//ClassPathXmlApplicationContext: 是ApplicationContext的接口实现类,该实现类从类路径下来加载配置文件
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.从IOC容器中获取Bean实例
//利用ID定位到IOC容器中的Bean
HelloWord helloworld = (HelloWord) ctx.getBean("helloworld");
//3.调用Hello方法
helloworld.Hello();
3.属性注入
- 属性注入即通过setter方法注入Bean的属性值或依赖的对象
- 属性注入使用< propety>元素,使用name属性指定Bean的属性名称,value属性或< value>子节点指定属性值
<bean id="helloworld" class="com.atguigu.spring.beans.HelloWord">
<property name="name" value="s11"></property>
</bean>
- 通过构造方法注入Bean的属性值或依赖的对象,它保证了Bean实例在实例化以后就可以使用
- 构造器注入在< constructor-arg>元素里声明属性,< constructor-arg>中没有name属性
<bean id="Car2" class="com.atguigu.spring.beans.Car">
<constructor-arg value="Baoma" ></constructor-arg>
<constructor-arg >
<!--如果字面值包含特殊字符可以使用<![CDATA[]]> -->
<value><![CDATA[<Beijing>^]]></value>
</constructor-arg>
<constructor-arg value="240" ></constructor-arg>
</bean>
4.字面值
- 字面值:可用字符串表示的值,可以通过< value>元素标签或value属性值注入
- 基本数据类型及其封装类、String等类型都可以采取字面值注入的方式
- 若字面值中包含特殊字符,可以使用<![CDATA[]]>把字面值包裹起来
5.引用其他Bean
- 组成应用程序的Bean经常需要相互协作以完成应用程序的功能。要使Bean能够相互访问,就必须在Bean配置文件中指定对Bean的引用
- 在Bean的配置文件中,可以通过< ref>元素或ref属性为Bean的属性或构造器参数指定对Bean的引用
- 也可以在属性或构造器里包含Bean的声明,这样的Bean称为内部Bean
<bean id="person" class="com.atguigu.spring.beans.Person">
<property name="name" value="Tom"></property>
<property name="age" value="24"></property>
<!-- 可以使用property的ref属性建立bean之间的引用关系 -->
<property name="car" ref="Car2"></property>
</bean>
<bean id="person3" class="com.atguigu.spring.collections.Person">
<property name="name" value="Mike"></property>
<property name="age" value="20"></property>
<property name="cars">
<list>
<ref bean="Car"/>
<ref bean="Car2"/>
</list>
</property>
</bean>
内部Bean,不能被外部引用
<!-- 内部Bean,只能在内部使用,不能被外部引用-->
<property name="car">
<bean id="car3" class="com.atguigu.spring.beans.Car">
<constructor-arg value="ford"></constructor-arg>
<constructor-arg value="changan"></constructor-arg>
<constructor-arg value="20000000" type="double"></constructor-arg>
</bean>
</property>
6.注入参数详解
- 可以使用专用的< null/>元素标签为Bean的字符串或其他对象类型的属性注入null值
- 和Struts、Hiberante等框架一样,Spring支持级联属性配置
<constructor-arg><null/></constructor-arg>
7.集合属性
- 在Spring中可以通过一组内置的xml标签(例如:< list>、< set>、< map>)来配置集合属性
- 配置java.util.List类型的属性,需要指定< list>标签,在标签里包含一些元素,这些标签可以通过< value>指定简单的常量值,通过< ref>指定对其他Bean的引用,通过< bean>指定内置Bean的定义。通过< null/>指定空元素,甚至可以内嵌其他元素。
- 数组的定义和List的一样,都使用< list>
- 配置java.util.Set需要使用< set>标签,定义元素的方法与List一样
- java.util.Map通过< map>标签定义,< map>标签里可以使用多个< entry>作为子标签。每个条目包含一个键和一个值
- 必须在< key>标签里定义键
- 因为键和值的类型没有限制,所以可以自由的为他们指定< value>、< ref>、< bean>、< null/>元素
- 可以将Map的键和值作为< entry>的属性定义:简单常量使用key和value来定义;Bean引用key-ref和value-ref属性定义
- 使用< props>定义 java.util.Properties,该标签使用多个< prop>作为子标签,每个< prop>标签必须定义key属性
<bean id="person3" class="com.atguigu.spring.collections.Person">
<property name="name" value="Mike"></property>
<property name="age" value="20"></property>
<property name="cars">
<list>
<ref bean="Car"/>
<ref bean="Car2"/>
</list>
</property>
</bean>
<!-- 配置Map类型属性值 -->
<bean id="newPerson" class="com.atguigu.spring.collections.Newperson">
<property name="name" value="lala"></property>
<property name="age" value="29"></property>
<property name="cars">
<map>
<entry key="AA" value-ref="Car"></entry>
<entry key="BB" value-ref="Car2"></entry>
</map>
</property>
</bean>
<!-- 配置properties属性值 -->
<bean id="datasource" class="com.atguigu.spring.collections.DataSource">
<property name="properties">
<!-- 使用props和prop子节点来为Properties属性赋值 -->
<props>
<prop key="user">root</prop>
<prop key="password">1234</prop>
<prop key="jdbcUrl">.....</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
8.使用utility scheme定义集合
- 使用基本的集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同的Bean之间共享集合
- 可以使用util scheme里的集合标签定义独立的集合Bean。需要注意的是,必须在< beans>根元素里添加util scheme
<!-- 配置单例的集合bean,以供多个bean进行引用,需要util命名空间 -->
<util:list id="cars">
<ref bean="Car"/>
<ref bean="Car2"/>
</util:list>
9.使用p命名空间
- 为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息
- Spring从2.5版本开始引入了一个新的p命名空间,可以通过< bean>元素属性的方式配置Bean的属性
- 使用p命名空间后,基于XML的配置方式将进一步简化
<!-- 通过p命名空间为bean的属性赋值,需要先导入p命名空间,相对于传统的命名方式更加简洁 -->
<bean id="person5" class="com.atguigu.spring.collections.Person" p:age="30"
p:name="Queen" p:cars-ref="cars">
</bean>
10.XML配置里的Bean自动装配
- Spring IOC 容器可以自动装配Bean。需要做的仅仅是在< bean>的autowire属性里指定自动装配的模式
- byType(根据类型自动装配):若IOC容器中有多个与目标Bean类型一致的Bean。在这种情况下,Spring将无法判定哪个Bean最适合该属性,所以不能执行自动装配
- byName(根据名称自动装配):必须将目标Bean的名称和属性名设置的完全相同
- constructor(通过构造器自动装配):当Bean中存在多个构造器时,此种自动装配方式将会很复杂,不推荐使用
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.3.xsd">
<bean id="address" class="com.atguigu.spring.autowire.Address"
p:city="Beijing" p:street="lantian">
</bean>
<bean id="car" class="com.atguigu.spring.autowire.Car"
p:brand="benchi" p:price="2000000"></bean>
<!-- 根据autowire属性自动装配的方式,
byName根据bean的名字和当前bean的setter风格和属性自动装配,若有匹配的,进行自动装配,若没有匹配的,则不装配
byType根据bean的类型和当前bean的属性的类型进行自动装配。若IOC容器中有一个以上的类型匹配的bean,则抛异常。
-->
<bean id="person" class="com.atguigu.spring.autowire.Person"
p:name="Tom" autowire="byName"></bean>
</beans>
通过byType装配
<bean id="address2" class="com.atguigu.spring.autowire.Address"
p:city="Beijing" p:street="lantian">
</bean>
<bean id="car" class="com.atguigu.spring.autowire.Car"
p:brand="benchi" p:price="2000000"></bean>
<!-- 根据autowire属性自动装配的方式,
byName根据bean的名字和当前bean的setter风格和属性自动装配,若有匹配的,进行自动装配,若没有匹配的,则不装配
byType根据bean的类型和当前bean的属性的类型进行自动装配。若IOC容器中有一个以上的类型匹配的bean,则抛异常。
-->
<bean id="person" class="com.atguigu.spring.autowire.Person"
p:name="Tom" autowire="byType"></bean>
11.继承、依赖Bean配置
- Spring允许继承bean的配置,被继承的bean称为父bean,继承的bean称为子bean
- 子bean从父bean中继承配置,包括bean的属性配置
- 子bean也可以覆盖从父bean继承过来的配置
- 父bean可以作为配置模板,也可以作为bean实例。若只想把父bean作为模板,可以设置bean的abstract属性为true,这样Spring将不会实例化这个Bean
- 并不是< bean>元素里的所有属性都会被继承。比如:autowire、abstract等
- 也可以忽略父Bean的class属性,让子bean指定自己的类,而共享相同的属性配置。但此时abstract必须设为true。
- Spring允许用户通过depends-on属性设定Bean前置依赖的Bean,前置依赖的Bean会在本bean实例化之前创建好
- 如果前置依赖于多个bean,则可以通过逗号、空格的方式配置bean的名称
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="address" p:city="beijing" p:street="wudaokou" abstract="true"></bean>
<!--abstract="true"抽象bean,只可以被继承,不可以被实例化,若一个bean的class属性没有被指定,则该bean必须是一个抽象bean -->
<!-- bean配置的继承:使用bean的parent属性指定继承哪个bean的配置 -->
<bean id="address2" class="com.atguigu.spring.autowire.Address"
p:street="lala" parent="address"></bean>
<bean id="address3" class="com.atguigu.spring.autowire.Address"
parent="address"></bean>
<bean id="car" class="com.atguigu.spring.autowire.Car"
p:brand="beike" p:price="50000"></bean>
<bean id="person" class="com.atguigu.spring.autowire.Person"
p:name="Chen" p:address-ref="address2" depends-on="car"></bean>
</beans>