Spring框架自学之路(二)

(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>



            

            



猜你喜欢

转载自blog.csdn.net/qq_38166944/article/details/79768422