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/

浙公网安备 33010602011771号