002SpringIOC002基于XML文件配置Bean

1 管理普通Bean

1.1 创建对象

在配置文件中使用bean标签可以实现对象的创建。

配置如下:

1 <bean id="user" class="com.demo.spring.User"></bean>

默认使用的是类中的无参构造方法。

bean标签中的属性说明:

id属性:表示对象的唯一标识。

class属性:创建的对象所在的类的全路径。

name属性:和id属性作用类似,可以使用特殊符号,但使用较少,早期使用的属性。

1.2 注入属性

1.2.1 通过setter方法注入属性

这种方式需要使用property标签,需要提供无参构造方法,以及定义属性及其setter方法。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2     <property name="name" value="张三"></property>
3     <property name="age" value="22"></property>
4 </bean>

property标签中的属性说明:

name属性:对象的属性名称。

value属性:对象的属性值。

1.2.2 通过构造器注入属性

这种方式需要使用constructor-arg标签,需要提供有参构造方法,以及定义属性但不要求有setter方法。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2     <constructor-arg name="name" value="张三"></constructor-arg>
3     <constructor-arg name="age" value="22"></constructor-arg>
4 </bean>

constructor-arg标签中的属性说明:

name属性:对象的属性名称。

value属性:对象的属性值。

type属性:对象的属性对应的类型,可省略。如果是基本类型就写基本类型,如果是引用类型就写全类名。

index属性:按照构造器中属性的顺序注入属性,很少用。构造器中属性的顺序从0开始。

1.2.3 通过名称空间注入属性

可以使用p名称空间设置属性,但较少使用。

这种方式需要使用p属性,需要提供无参构造方法,以及定义属性及其setter方法。

需要添加p名称空间:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3        xmlns:p="http://www.springframework.org/schema/p"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

配置如下:

1 <bean id="user" class="com.demo.spring.User" p:name="张三" p:age="22"></bean>

1.3 注入特殊属性

1.3.1 注入Null值

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2     <property name="name">
3         <null />
4     </property>
5 </bean>

1.3.2 注入包含特殊符号的值

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2     <property name="name">
3         <value><![CDATA[张三]]></value>
4     </property>
5 </bean>

1.4 注入其他Bean对象

1.4.1 注入外部Bean

可以通过注入外部Bean的方式注入其他Bean对象。

配置如下:

1 <bean id="sz" class="com.demo.spring.Address">
2     <property name="province" value="广东省"></property>
3     <property name="city" value="深圳市"></property>
4 </bean>
5 <bean id="user" class="com.demo.spring.User">
6     <property name="name" value="张三"></property>
7     <property name="address" ref="sz"></property>
8 </bean>

property标签中的属性说明:

ref属性:外部Bean的id属性。

1.4.2 注入内部的Bean

可以通过注入内部Bean的方式注入其他Bean对象。

配置如下:

1 <bean id="user" class="com.demo.spring.User">
2     <property name="name" value="张三"></property>
3     <property name="address">
4         <bean id="sz" class="com.demo.spring.Address">
5             <property name="province" value="广东省"></property>
6             <property name="city" value="深圳市"></property>
7         </bean>
8     </property>
9 </bean>

1.4.3 注入级联属性

可以注入其他Bean的属性,也就是注入级联属性。

需要提供Bean的getter方法以及Bean属性的getter方法。

配置如下:

1 <property name="address.province" value="山东省"></property>

1.4.4 自动装配

可以根据装配方式自动引用其他Bean对象,不经常使用。

配置如下:

1 <bean id="sz" class="com.demo.spring.Address">
2     <property name="province" value="广东省"></property>
3     <property name="city" value="深圳市"></property>
4 </bean>
5 <bean id="user" class="com.demo.spring.User" autowire="byName">
6     <!--<property name="address" ref="sz"></property>-->
7 </bean>

bean标签中的属性说明:

autowire属性:外部Bean的引用方式。

autowire属性有如下取值:

byName:根据属性名进行装配。这种方式会在配置文件中查找id和属性名一样的Bean,如果查到多个则报错,如果没有查到则设置null。

byType:根据属性类型进行装配。这种方式会在配置文件中查找和属性类型一样的Bean,如果查到多个则报错,如果没有查到则设置null。

constructor:根据构造器进行装配。不常用。

default:不自动装配,设置属性为null。默认使用此种方式。

1.5 注入集合属性

1.5.1 注入数组属性

需要定义数组属性并提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2     <property name="brand" value="奥迪"></property>
 3     <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6     <property name="name" value="张三"></property>
 7     <property name="pets">
 8         <array>
 9             <value>猫</value>
10             <value>狗</value>
11         </array>
12     </property>
13     <property name="cars">
14         <array>
15             <ref bean="audi"></ref>
16             <bean id="volvo" class="com.demo.spring.Car">
17                 <property name="brand" value="沃尔沃"></property>
18                 <property name="color" value="黑色"></property>
19             </bean>
20         </array>
21     </property>
22 </bean>

标签说明如下:

array标签:定义数组属性。

value标签:定义数组中的基本类型和字符串类型的成员。

ref标签:定义数组中的引用类型的成员,外部注入Bean。

bean标签:定义数组中的引用类型的成员,内部注入Bean。

1.5.2 注入List属性

需要定义List属性并提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2     <property name="brand" value="奥迪"></property>
 3     <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6     <property name="name" value="张三"></property>
 7     <property name="pets">
 8         <list>
 9             <value>猫</value>
10             <value>狗</value>
11         </list>
12     </property>
13     <property name="cars">
14         <list>
15             <ref bean="audi"></ref>
16             <bean id="volvo" class="com.demo.spring.Car">
17                 <property name="brand" value="沃尔沃"></property>
18                 <property name="color" value="黑色"></property>
19             </bean>
20         </list>
21     </property>
22 </bean>

标签说明如下:

list标签:定义List属性。

value标签:定义List中的基本类型和字符串类型的成员。

ref标签:定义List中的引用类型的成员,外部注入Bean。

bean标签:定义List中的引用类型的成员,内部注入Bean。

1.5.3 注入Set属性

需要定义Set属性并提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2     <property name="brand" value="奥迪"></property>
 3     <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="user" class="com.demo.spring.User">
 6     <property name="name" value="张三"></property>
 7     <property name="pets">
 8         <set>
 9             <value>猫</value>
10             <value>狗</value>
11         </set>
12     </property>
13     <property name="cars">
14         <set>
15             <ref bean="audi"></ref>
16             <bean id="volvo" class="com.demo.spring.Car">
17                 <property name="brand" value="沃尔沃"></property>
18                 <property name="color" value="黑色"></property>
19             </bean>
20         </set>
21     </property>
22 </bean>

标签说明如下:

set标签:定义Set属性。

value标签:定义Set中的基本类型和字符串类型的成员。

ref标签:定义Set中的引用类型的成员,外部注入Bean。

bean标签:定义Set中的引用类型的成员,内部注入Bean。

1.5.4 注入Map属性

需要定义Map属性并提供setter方法。

配置如下:

 1 <bean id="audi" class="com.demo.spring.Car">
 2     <property name="brand" value="奥迪"></property>
 3     <property name="color" value="白色"></property>
 4 </bean>
 5 <bean id="mazda" class="com.demo.spring.Car">
 6     <property name="brand" value="马自达"></property>
 7     <property name="color" value="红色"></property>
 8 </bean>
 9 <bean id="user" class="com.demo.spring.User">
10     <property name="name" value="张三"></property>
11     <property name="pets">
12         <map>
13             <entry key="cat" value="猫"></entry>
14             <entry key="dog" value="狗"></entry>
15         </map>
16     </property>
17     <property name="cars">
18         <map>
19             <entry key="奥迪" value-ref="audi"></entry>
20             <entry key="马自达" value-ref="mazda"></entry>
21             <entry key="沃尔沃">
22                 <bean id="volvo" class="com.demo.spring.Car">
23                     <property name="brand" value="沃尔沃"></property>
24                     <property name="color" value="黑色"></property>
25                 </bean>
26             </entry>
27         </map>
28     </property>
29 </bean>

标签及属性说明如下:

map标签:定义Map属性。

entry标签:定义Map中的成员。

key属性:定义Map中的基本类型和字符串类型的key。

key-ref属性:定义Map中的引用类型的key。

value属性:定义Map中的基本类型和字符串类型的value。

value-ref属性:定义Map中的引用类型的value,外部注入Bean。

bean标签:定义Map中的引用类型的value,内部注入Bean。

1.6 抽取集合属性

使用util名称空间可以将集合属性抽取出来作为单独的一个Bean。

需要添加util名称空间:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3        xmlns:util="http://www.springframework.org/schema/util"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5                            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

配置如下:

 1 <util:map id="pets">
 2     <entry key="cat" value="猫"></entry>
 3     <entry key="dog" value="狗"></entry>
 4 </util:map>
 5 <util:map id="cars">
 6     <entry key="奥迪" value-ref="audi"></entry>
 7     <entry key="马自达" value-ref="mazda"></entry>
 8     <entry key="沃尔沃">
 9         <bean id="volvo" class="com.demo.spring.Car">
10             <property name="brand" value="沃尔沃"></property>
11             <property name="color" value="黑色"></property>
12         </bean>
13     </entry>
14 </util:map>
15 <bean id="audi" class="com.demo.spring.Car">
16     <property name="brand" value="奥迪"></property>
17     <property name="color" value="白色"></property>
18 </bean>
19 <bean id="mazda" class="com.demo.spring.Car">
20     <property name="brand" value="马自达"></property>
21     <property name="color" value="红色"></property>
22 </bean>
23 <bean id="user" class="com.demo.spring.User">
24     <property name="name" value="张三"></property>
25     <property name="pets" ref="pets"></property>
26     <property name="cars" ref="cars"></property>
27 </bean>

2 管理工厂Bean

2.1 是什么

Spring中有两种类型的Bean,一种是普通Bean,另外一种是工厂Bean。

对于普通Bean来说,配置文件中定义的Bean类型就是获取Bean的返回类型。但对于工厂Bean来说,配置文件中定义的Bean类型并不是获取Bean的返回类型。

创建工厂Bean的步骤:

1)创建工厂类,实现FactoryBean接口并实现方法。

2)在实现的方法中定义返回的Bean类型。

2.2 使用

创建工厂类:

 1 public class Animal implements FactoryBean<Cat> {
 2     @Override
 3     public Cat getObject() throws Exception {
 4         return new Cat();
 5     }
 6     @Override
 7     public Class<?> getObjectType() {
 8         return null;
 9     }
10 }

在配置文件中创建对象:

1 <bean id="cat" class="com.demo.spring.Animal"></bean>

测试:

1 @Test
2 public void testAdd() {
3     // 加载配置文件
4     ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
5     // 获取配置的对象
6     Cat cat = context.getBean("cat", Cat.class);
7     // 使用对象
8     System.out.println(cat);
9 }

3 Bean的作用域

3.1 默认

在IOC容器创建的时候,会将配置文件中的对象全部创建并初始化。

默认创建的对象是单实例的,即多次获取到的对象是同一个对象。

测试:

1 @Test
2 public void testAdd() {
3     ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
4     System.out.println(context.getBean("cat", Cat.class));
5     System.out.println(context.getBean("cat", Cat.class));
6 }

两次获取的地址相同,说明是同一对象,也表名默认情况下是单例的。

3.2 配置

在配置文件中可以使用bean标签的scope属性修改创建对象的方式。

scope属性的取值:

1 singleton:单实例,容器初始化时创建对象,默认的配置方式。
2 prototype:多实例,容器初始化时不创建对象,每次使用时创建对象,可以动态选择对象。
3 request:在Web项目中,容器初始化时不创建对象,每个请求创建对象。
4 session:在Web项目中,容器初始化时不创建对象,每个会话创建对象。

配置多实例如下:

1 <bean id="cat" class="com.demo.spring.Animal" scope="prototype"></bean>

4 Bean的生命周期

4.1 是什么

Bean的生命周期指的是Bean从创建到销毁的全过程。

4.2 生命周期

4.2.1 顺序

1)通过无参构造器创建Bean实例。

2)给Bean设置属性值和Bean之间的引用。

3)执行Bean的初始化方法,需要设置方法。

4)获取并使用Bean。

5)执行Bean的销毁方法,需要设置方法,在手动销毁容器时自动调用。

4.2.2 演示

创建类:

 1 public class User {
 2     public String name;
 3     public User() {
 4         System.out.println("Step1 通过无参构造器创建Bean实例");
 5     }
 6     public void setName(String name) {
 7         System.out.println("Step2 给Bean设置属性值和Bean之间的引用");
 8         this.name = name;
 9     }
10     public void initMethod() {
11         System.out.println("Step3 执行Bean的初始化方法");
12     }
13     public void destroyMethod() {
14         System.out.println("Step5 执行Bean的销毁方法");
15     }
16 }

配置文件:

1 <bean id="user" class="com.demo.spring.User" init-method="initMethod" destroy-method="destroyMethod">
2     <property name="name" value="张三"></property>
3 </bean>

测试方法:

1 @Test
2 public void testAdd() {
3     ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
4     User user = context.getBean("user", User.class);
5     System.out.println("Step4 获取并使用Bean");
6     System.out.println(user);
7     // Step5 手动销毁容器,执行Bean的销毁方法
8     context.close();
9 }

执行结果:

1 Step1 通过无参构造器创建Bean实例
2 Step2 给Bean设置属性值和Bean之间的引用
3 Step3 执行Bean的初始化方法
4 Step4 获取并使用Bean
5 com.demo.spring.User@5123a213
6 Step5 执行Bean的销毁方法

4.3 后置处理器

4.3.1 定义

后置处理器会在执行Bean的初始化方法前后执行对应的方法,需要实现接口并在配置文件中配置。

后置处理器会为当前配置文件中的所有Bean实例都添加处理方法。

4.3.2 演示

创建后置处理器类:

 1 public class DemoBeanPost implements BeanPostProcessor {
 2     @Override
 3     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 4         System.out.println("Step3 执行Bean的初始化方法之前执行");
 5         return bean;
 6     }
 7     @Override
 8     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 9         System.out.println("Step3 执行Bean的初始化方法之后执行");
10         return bean;
11     }
12 }

配置文件:

1 <bean id="demoBeanPost" class="com.demo.spring.DemoBeanPost"></bean>

执行结果:

1 Step1 通过无参构造器创建Bean实例
2 Step2 给Bean设置属性值和Bean之间的引用
3 Step3 执行Bean的初始化方法之前执行
4 Step3 执行Bean的初始化方法
5 Step3 执行Bean的初始化方法之后执行
6 Step4 获取并使用Bean
7 com.demo.spring.User@24b1d79b
8 Step5 执行Bean的销毁方法

5 引入外部文件

使用context名称空间可以引入外部文件,并使用其中的配置,多用于创建数据库连接池。

需要添加context名称空间:

1 <beans xmlns="http://www.springframework.org/schema/beans"
2        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3        xmlns:context="http://www.springframework.org/schema/context"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
5                            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">

配置如下:

1 <context:property-placeholder location="classpath:jdbc.properties"></context:property-placeholder>
2 <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
3     <property name="username" value="${mysql.username}"></property>
4     <property name="password" value="${mysql.password}"></property>
5     <property name="url" value="${mysql.url}"></property>
6     <property name="driverClassName" value="${mysql.driver}"></property>
7 </bean>

 

上一篇:Sping进阶


下一篇:Android 面试题之ContentProvider使用+实例,被面试官问的Android问题难倒了