(02Day)
昨天我用spring写了第一个HelloWorld程序并且了解了什么是IOC,DI,那么今天我们来看看在spring配置文件(applicationContext.xml)中<Bean>属性配置的一些细节。(下面有些代码要用到上一篇中的代码,最好在上次代码的基础上进行测试)
(1)value元素如何添加特殊符号
若需要添加特殊符号,可以以使用 <![CDATA[]]> 把字面值包裹起来。
例子如下:
<bean id="car2" class="com.etc.Car">
<constructor-arg value="奔驰" type="java.lang.String"></constructor-arg>
<!-- 若是在value中要有特殊字符 那么需要加<![CDATA[]]>,例:如下 -->
<constructor-arg type="java.lang.String">
<value><![CDATA[<上海^>]]></value>
</constructor-arg>
<!-- <constructor-arg value="250" type="int"></constructor-arg> -->
<!-- 上边 value = 250 spring 帮你自动转化成int类型了,也可以使用下面用value子节点配置 -->
<constructor-arg type="int">
<value>250</value>
</constructor-arg>
</bean>
(2)如何引用其他的Bean
在平时我们写程序的时候,难免会遇到一个类中包含另一个类,那么在spring中我们就需要在Bean的配置文件中指定对Bean的引用。
在 Bean 的配置文件中, 可以通过 <ref> 元素或 ref 属性为 Bean 的属性或构造方法参数指定对 Bean 的引用。也可以在属性或构造方法里包含Bean的声明,这样的Bean称为内部Bean。例子如下:
<!-- 引用其他Bean,ref指向IOC容器中其他的Bean -->
<bean id="person1" class="com.etc.Person">
<property name="name" value="Garon"></property>
<property name="age" value="22"></property>
<!-- <property name="car" ref="car2"></property> -->
<!-- 也可以使用ref子节点来配置
<property name="car">
<ref bean="car2"/>
</property>
-->
<!-- 内部Bean 不能被外部使用,只能在内部使用。id设了没有意义,所以一般不设置id-->
<property name="car">
<bean class="com.etc.Car">
<constructor-arg value="福特" type="java.lang.String"></constructor-arg>
<constructor-arg value="长安" type="java.lang.String"></constructor-arg>
<constructor-arg value="230000" type="double"></constructor-arg>
</bean>
</property>
</bean>
<!-- 用构造方法的方式关联其他的Bean,和属性输注是相似的 -->
<bean id="person2" class="com.etc.Person">
<constructor-arg value="jim"></constructor-arg>
<constructor-arg value="26"></constructor-arg>
<!--<constructor-arg ref="car2"></constructor-arg> -->
<!-- 测试赋值null,实际上没多大意义,因为如果不给它赋值,它本身就是null
<constructor-arg><null/></constructor-arg>
-->
<!-- spring支持级联属性,car2为IOC容器中其他的Bean,car.maxSpeed为person中内部类car的maxSpeed属性 -->
<!-- 注意spring和struts2不一样 如果在person中没为car赋值的话,spring是不允许使用级联的,而struts2,如果car值为null,为自动为car赋值 -->
<constructor-arg ref="car2"></constructor-arg>
<property name="car.maxSpeed" value="333" ></property>
</bean>
(3)集合属性
在开发中一般都hi用到集合属性的,那么在spring中如何配置集合属性呢?现在就让我们来看看在spring的配置文件中如何配置集合属性。
3-1 首先写一个带有集合List的Person类
package com.etc2;
import java.util.List;
import com.etc.Car;
public class Person {
private String name;
private int age;
private List<Car> cars;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}
public Person(String name, int age, List<Car> cars) {
super();
this.name = name;
this.age = age;
this.cars = cars;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", cars=" + cars + "]";
}
}
3-2-1 在spring的配置文件(applicationContext.xml)中配置(List,set和数组是差不多的所以就使用List作为测试)
<!-- 集合属性 list,set,数组和list使用是差不多的 -->
<bean id="person3" class="com.etc2.Person">
<property name="name" value="jack"></property>
<property name="age" value="33" ></property>
<property name="cars" >
<list>
<ref bean="car1"/>
<ref bean="car2"/>
<!-- 也可以在list中定义内部Bean -->
<bean class="com.etc.Car">
<constructor-arg value="宝马" type="java.lang.String"></constructor-arg>
<constructor-arg value="上海" type="java.lang.String"></constructor-arg>
<constructor-arg value="630000" type="double"></constructor-arg>
</bean>
</list>
</property>
</bean>
3-2-2 那么Map在spring中又如何配置呢?Map中常用到的数据库配置文件properties又是如配置的?
首先创建一个DataSource类模拟数据库连接和NewPreson类模拟Map集合使用
package com.etc2;
import java.util.Properties;
public class DataSource {
//用来链接数据库的。这里模拟下。以便后续spring整合Hibernate使用
private Properties properties;
public Properties getProperties() {
return properties;
}
public void setProperties(Properties properties) {
this.properties = properties;
}
@Override
public String toString() {
return "DataSource [properties=" + properties + "]";
}
}
package com.etc2;
import java.util.Map;
import com.etc.Car;
public class NewPerson {
private String name;
private int age;
private Map<String,Car> cars;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Map<String, Car> getCars() {
return cars;
}
public void setCars(Map<String, Car> cars) {
this.cars = cars;
}
@Override
public String toString() {
return "NewPerson [name=" + name + ", age=" + age + ", cars=" + cars
+ "]";
}
}
然后在spring配置文件中进行配置
<!-- 集合Map -->
<bean id="newPerson" class="com.etc2.NewPerson">
<property name="name" value="jane"></property>
<property name="age" value="28"></property>
<property name="cars">
<!-- 使用map节点及map的entry子节点配置Map类型的成员变量 -->
<map>
<entry key="QQQ" value-ref="car1"></entry>
<entry key="WWW" value-ref="car2"></entry>
</map>
</property>
</bean>
<!-- 配置properties 后面spring和hibernate整合的时候需要用到-->
<bean id="dataSource" class="com.etc2.DataSource">
<property name="properties">
<props>
<!-- 作为一个模拟 -->
<prop key="user">root</prop>
<prop key="password">1234</prop>
<prop key="jdbcUrl">jdbc:mysql://test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
3-3 到这里不知道你们有没有想到,如果我有一个集合有很多对象都需要使用,那么我们是一个个的写呢?还是有什么更方便的方法,答案是肯定有的。
首先在spring配置文件中(applicationContext.xml)点击命名空间导入Util。
然后就可以在spring配置文件中进行配置(通过<util:list>标签进行配置单例集合)
<!-- 配置单例集合beam,以供bean进行引用,需要导入util命名空间 -->
<util:list id="cars">
<ref bean="car1"/>
<ref bean="car2"/>
</util:list>
<bean id="person4" class="com.etc2.Person">
<property name="name" value="jack"></property>
<property name="age" value="35"></property>
<property name="cars" ref="cars"></property>
</bean>
(4)P命名空间
为了简化xml的配置,在spring2.5开始引入一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean的属性。
<!-- 通过p命名空间为Bean的属性赋值,需先导入p命名空间 .相对与以前的配置方式这样更加的便捷-->
<bean id="person5" class="com.etc2.Person" p:age="38" p:name="张三" p:cars-ref="cars"></bean>
这样是不是更不会那么繁琐呢。注:p也是需要先导入p命名空间的
(5)测试文件以及整个spring配置文件
测试文件
package com.etc2;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main3 {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
Person person = (Person) ctx.getBean("person3");
System.out.println(person);
NewPerson newperson = (NewPerson) ctx.getBean("newPerson");
System.out.println(newperson);
DataSource datasource = (DataSource) ctx.getBean("dataSource");
System.out.println(datasource.getProperties());
person = (Person) ctx.getBean("person4");
System.out.println("util:"+person);
person = (Person) ctx.getBean("person5");
System.out.println("P:"+person);
}
}
spring配置文件
<?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.0.xsd">
<!--
配置Bean
class:bean的全类名,通过反射的方式在IOC容器中创建Bean,所以要求Bean中必须有无参的构造方法
id:标识容器中的Bean。id唯一。
-->
<bean id="helloWorld" class="com.etc.HelloWorld">
<!-- (最常用的方式)通过set方法注入,userName就是setUserName方法去掉set,并把首字母小写 -->
<property name="userName" value = "World"></property>
</bean>
<!-- 通过构造方法来配置Bean index为属性在构造方法中参数的位置 -->
<bean id="car1" class="com.etc.Car">
<constructor-arg value="奥迪" index="0"></constructor-arg>
<constructor-arg value="上海" index="1"></constructor-arg>
<constructor-arg value="300000" index="2"></constructor-arg>
</bean>
<!-- 通过构造方法来配置Bean,可以用指定参数的位置和参数的类型!以区分重载构造方法-->
<bean id="car2" class="com.etc.Car">
<constructor-arg value="奔驰" type="java.lang.String"></constructor-arg>
<!-- 若是在value中要有特殊字符 那么需要加<![CDATA[]]>,例:如下 -->
<constructor-arg type="java.lang.String">
<value><![CDATA[<上海^>]]></value>
</constructor-arg>
<!-- <constructor-arg value="250" type="int"></constructor-arg> -->
<!-- 上边 value = 250 spring 帮你自动转化成int类型了,也可以使用下面用value子节点配置 -->
<constructor-arg type="int">
<value>250</value>
</constructor-arg>
</bean>
<!-- 引用其他Bean,ref指向IOC容器中其他的Bean -->
<bean id="person1" class="com.etc.Person">
<property name="name" value="Garon"></property>
<property name="age" value="22"></property>
<!-- <property name="car" ref="car2"></property> -->
<!-- 也可以使用ref子节点来配置
<property name="car">
<ref bean="car2"/>
</property>
-->
<!-- 内部Bean 不能被外部使用,只能在内部使用。id设了没有意义,所以一般不设置id-->
<property name="car">
<bean class="com.etc.Car">
<constructor-arg value="福特" type="java.lang.String"></constructor-arg>
<constructor-arg value="长安" type="java.lang.String"></constructor-arg>
<constructor-arg value="230000" type="double"></constructor-arg>
</bean>
</property>
</bean>
<!-- 用构造方法的方式关联其他的Bean,和属性输注是相似的 -->
<bean id="person2" class="com.etc.Person">
<constructor-arg value="jim"></constructor-arg>
<constructor-arg value="26"></constructor-arg>
<!--<constructor-arg ref="car2"></constructor-arg> -->
<!-- 测试赋值null,实际上没多大意义,因为如果不给它赋值,它本身就是null
<constructor-arg><null/></constructor-arg>
-->
<!-- spring支持级联属性,car2为IOC容器中其他的Bean,car.maxSpeed为person中内部类car的maxSpeed属性 -->
<!-- 注意spring和struts2不一样 如果在person中没为car赋值的话,spring是不允许使用级联的,而struts2,如果car值为null,为自动为car赋值 -->
<constructor-arg ref="car2"></constructor-arg>
<property name="car.maxSpeed" value="333" ></property>
</bean>
<!-- 集合属性 list,set,数组和list使用是差不多的 -->
<bean id="person3" class="com.etc2.Person">
<property name="name" value="jack"></property>
<property name="age" value="33" ></property>
<property name="cars" >
<list>
<ref bean="car1"/>
<ref bean="car2"/>
<!-- 也可以在list中定义内部Bean -->
<bean class="com.etc.Car">
<constructor-arg value="宝马" type="java.lang.String"></constructor-arg>
<constructor-arg value="上海" type="java.lang.String"></constructor-arg>
<constructor-arg value="630000" type="double"></constructor-arg>
</bean>
</list>
</property>
</bean>
<!-- 集合Map -->
<bean id="newPerson" class="com.etc2.NewPerson">
<property name="name" value="jane"></property>
<property name="age" value="28"></property>
<property name="cars">
<!-- 使用map节点及map的entry子节点配置Map类型的成员变量 -->
<map>
<entry key="QQQ" value-ref="car1"></entry>
<entry key="WWW" value-ref="car2"></entry>
</map>
</property>
</bean>
<!-- 配置properties 后面spring和hibernate整合的时候需要用到-->
<bean id="dataSource" class="com.etc2.DataSource">
<property name="properties">
<props>
<!-- 作为一个模拟 -->
<prop key="user">root</prop>
<prop key="password">1234</prop>
<prop key="jdbcUrl">jdbc:mysql://test</prop>
<prop key="driverClass">com.mysql.jdbc.Driver</prop>
</props>
</property>
</bean>
<!-- 配置单例集合beam,以供bean进行引用,需要导入util命名空间 -->
<util:list id="cars">
<ref bean="car1"/>
<ref bean="car2"/>
</util:list>
<bean id="person4" class="com.etc2.Person">
<property name="name" value="jack"></property>
<property name="age" value="35"></property>
<property name="cars" ref="cars"></property>
</bean>
<!-- 通过p命名空间为Bean的属性赋值,需先导入p命名空间 .相对与以前的配置方式这样更加的便捷-->
<bean id="person5" class="com.etc2.Person" p:age="38" p:name="张三" p:cars-ref="cars"></bean>
</beans>