Spring-bean(二)

命名空间

自动装配

bean之间的关系:继承;依赖

使用外部属性文件

SpEL

bean的生命周期

bean的后置处理器

 

(一)util命名空间

当用list,set等集合时,不能将集合作为独立的bean定义,导致其他bean无法引用,不同的bean之间不能共享集合。所以,引入util标签。

1    <!-- 配置单例的集合bean,以供多个bean进行引用,需要导入util命名空间 -->
2     <util:list id="cars">
3         <ref bean="car" ></ref>
4         <ref bean="car2" ></ref>
5     </util:list>

 

1    <bean id="person" class="com.text.Person">
2         <property name="car" ref="cars"></property>
3     </bean>
4     <bean id="person2" class="com.text.Person">
5         <property name="car" ref="cars"></property>
6     </bean>

 

(二)p命名空间

1 <bean id="person" class="com.text.Person" p:name="tom" p:car-ref="cars"></bean>

 

bean自动装配(此时person这个bean会自动将car装配,与上面p命名空间实例代码等价)

1     <bean id="car" class="com.text.Car" p:name="baoma" p:speed="80" p:price="800000"></bean>
2     <!-- 可以使用autowire属性指定自动装配的方式,byName根据bean的名字和当前bean的setter风格的属性名进行自动装配,若匹配上,则自动匹配
3          byType根据bean的类型和当前bean的属性的类型进行自动装配,若ioc容器中有一个以上的类型匹配的bean,抛异常
4          -->
5     <bean id="person" class="com.text.Person" p:name="Tom" autowire="byName"></bean>

 

抽象bean以及bean的继承(autowire和abstract不会被继承)

1    <!-- 抽象bean,bean的abstract属性为true的bean,这样的bean不能被实例化,成为模板bean 
2     若某一个bean的class属性没有指定,则该bean必须是一个抽象bean-->
3     <bean id="car" p:name="baoma" p:speed="80" p:price="800000" abstract="true"></bean>
4     <!-- bean配置的继承,使用bean的parent属性指定继承哪个bean的配置 -->
5     <bean id="car2" class="com.text.Car" p:name="baoma" p:speed="80" parent="car"></bean>

 

依赖

1 <!-- 要求再配置Person时,必须有一个关联的car。换句话说Person这个bean依赖于Car这个bean -->
2 <bean id="person" class="com.text.Person" p:name="Tom" depends-on="cars"></bean>
3     

 

scope

1 <!-- 使用bean的scope属性来配置bean的作用域
2  默认Singleton: 单例,容器初始时创建bean实例,在整个容器的生命周期内只创建一个bean
3  prototype: 原型的,容器初始化时不创建bean的实例,而在每次请求时都创建一个新的bean实例,并返回 -->
4     <bean id="car" class="com.text.Car" scope="singleton"></bean>

 

使用外部属性文件

在配置文件里配置Bean时,有时需要在Bean的配置里混入系统部署的细节信息,如文件路径,数据源配置信息。而这些部署细节实际上需要和Bean配置相分离

1     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
2         <property name="user" value="root"></property>
3         <property name="password" value="root"></property>
4         <property name="driverClass" value="com.mysql.jdbc.Driver"></property>
5         <property name="jdbcUrl" value="jdbc:mysql:///bookclub"></property>
6     </bean>

当以后需要改配置时,需要在很多xml文件中寻找bean,十分麻烦,此时引入属性文件

1 user=root
2 password=root
3 driverClass=com.mysql.jdbc.Driver
4 jdbcUrl=jdbc:mysql:///bookclub
1    <context:property-placeholder location="classpath:db.properties"/>
2     
3     <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
4         <property name="user" value="${user}"></property>
5         <property name="password" value="${password}"></property>
6         <property name="driverClass" value="${driverClass}"></property>
7         <property name="jdbcUrl" value="${jdbcUrl}"></property>
8     </bean>

 

SpEL(为bean的动态赋值提供了方便)

可以实现:

1. 通过bean的id对bean进行引用

2. 调用方法以及引用对象中的属性

3. 计算表达式的值

4. 正则表达式的匹配

 1     <bean id="car" class="com.text.Car">
 2         <property name="name" value="audi"></property>
 3         <property name="price" value="12345"></property>
 4         <!-- 使用SpEL引用类的静态属性 -->
 5         <property name="speed" value="#{T(java.lang.Math).PI*100}"></property>
 6     </bean>
 7     
 8     <bean id="person" class="com.text.Person">
 9         <!-- 使用SpEL来应用其他bean的属性 -->
10         <property name="name" value="#{car.name}"></property>
11         <!-- 使用SpEL来应用其他bean -->
12         <property name="car" value="#{car}"></property>
13         <!-- 在SpEL中使用运算符 -->
14         <property name="info" value="#{car.price > 30000 ? '金领' : '白领'}"></property>
15     </bean>

 

bean的生命周期

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

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

3. 调用bean的初始化方法,前后可调用BeanPostProcessor 

4. bean可以使用了

5. 当容器关闭,调用bean的销毁方法

1 <bean id="car" class="com.text.Car" init-method="init" destroy-method="destroy">

在car.java中加入初始化方法和销毁方法

1    public void init() {
2         System.out.println("init/.");
3     }
4     public void destroy() {
5         System.out.println("destroy/.");
6     }

Main函数

1 public class Main {
2     public static void main(String[] args) throws SQLException {
3         ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("ApplicationContext.xml");
4         Car car = (Car)ctx.getBean("car");
5         System.out.println(car);
6         ctx.close();
7     }
8 }

 

bean的后置处理器

允许在调用初始化方法前后对bean进行额外的处理。对ioc容器的所有bean实例逐一处理。可修改返回的bean,甚至返回一个新的bean

典型应用:检查bean属性的正确性或根据特定的标准更改bean的属性

在set方法以及构造方法中加入输出

MyBeanPostProcessor.java

 1    public class MyBeanPostProcessor implements BeanPostProcessor {
 2 
 3     @Override
 4     public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 5         // TODO Auto-generated method stub
 6         System.out.println("postProcessBeforeInitialization:" + bean + "," + beanName);
 7         return bean;
 8     }
 9 
10     @Override
11     public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
12         // TODO Auto-generated method stub
13         System.out.println("postProcessAfterInitialization:" + bean + "," + beanName);
14         return bean;
15     }
16 
17 }

 

1     <!-- 配置bean的后置处理器 -->
2     <bean class="com.text.MyBeanPostProcessor"></bean>

 

输出顺序

car's contructor
setName:audi
setprice:12345
setspeed:314
postProcessBeforeInitialization:com.text.Car@cdbdf5,car
init/.
postProcessAfterInitialization:com.text.Car@cdbdf5,car
com.text.Car@cdbdf5
destroy/
posted @ 2016-04-09 16:39  七彩蝶  阅读(137)  评论(0)    收藏  举报