Spring学习(3)——注入属性值扩展

目录

一、字面值

二、引用其他Bean

用ref属性或者元素指定bean例子

用内部bean的列子

三、null值和级联属性

四、集合属性

用标签注入属性值的样例

注入Map类属性值:

定义java.util.Properties

五、使用utility scheme定义集合

六、使用P命名空间


上一篇学习了Bean的配置、Spring容器的基本实现、Bean注入值的方式,这一篇在Bean注入值的基础上,扩展的学习一下注入属性的一些技巧。

一、字面值

  1. 字面值,可用于字符串表示的值,可以通过<value>元素标签value属性进行注入;
  2. 基本数据类型及其封装类、String等类型都可以采用字面值注入;
  3. 若字面值中包含了特殊字符,可以使用<![CDATE[]]>把字面值包裹起来。

例如将id="car1"的Bean用字面值注入值(给corp注入的值是<^^GanSu^^>,给maxSpeed注入的值是180):

$注意:本例中Car.class,Main.class其他代码都在上一篇文章中:Spring学习(2)——bean的配置

	<!-- 通过字面值给corp和maxSpeed属性注入值 -->
	<bean id="car1" class="com.atguigu.spring.beans.Car">
		<constructor-arg value="Audi" type="java.lang.String"></constructor-arg>
		<constructor-arg type="java.lang.String">
			<value><![CDATA[<^^GanSu^^>]]></value>
		</constructor-arg>
		<constructor-arg type="int">
			<value>180</value>
		</constructor-arg>
	</bean>

执行结果是:

Car1: Car [brand=Audi, corp=<^^GanSu^^>, price=0.0, maxSpeed=180]

二、引用其他Bean

  1. 组成应用程序的Bean经常需要相互协作以完成应用程序的功能。要使Bean能够相互访问,就必须在Bean配置文件中指定对Bean的引用
  2. 在Bean的配置文件中,可以通过<ref>元素或ref属性为Bean的属性或者构造器参数指定对Bean的引用
  3. 也可以在属性或构造器里面含Bean的声明,这样的Bean成为内部Bean
  • 用ref属性或者<ref>元素指定bean例子

我们写一个Person类:

public class Person {
	private String name;
	private int age;
	private Car car;
	
	
	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 Car getCar() {
		return car;
	}
	public void setCar(Car car) {
		this.car = car;
	}
	
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
	}
}

在applicationContext.xml中的person的bean中注入car1:

	<!-- property的ref属性或<ref>元素家里bean之间的引用关系 -->
	<bean id="person" class="com.atguigu.spring.beans.Person">
		<property name="name" value="zhangsan"></property>
		<property name="age" value="26"></property>
		<!-- 用property的ref属性建立bean之间的引用关系 <property name="car" ref="car1"></property> -->
		<!-- <ref>元素家里bean之间的引用关系 -->
		<property name="car">
			<ref bean="car1" />
		</property>
	</bean>

在main中调用,查看注入的值:

	public static void main(String[] args) {
		Main main=new Main();
		main.testBeanAdd();
	}

	private void testBeanAdd() {
		ApplicationContext cxt=new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) cxt.getBean("person");
		System.out.println(person);
	}

执行结果为:

Person [name=zhangsan, age=26, car=Car [brand=Audi, corp=<^^GanSu^^>, price=0.0, maxSpeed=180]]
  • 用内部bean的列子

但是内部bean,不能被外部使用,只能在内部使用。

Person不变,xml改写成内部bean的实现方式:

	<!-- 内部bean实现bean之间的引用关系 -->
	<bean id="person" class="com.atguigu.spring.beans.Person">
		<property name="name" value="zhangsan"></property>
		<property name="age" value="26"></property>
		<property name="car">
			<bean class="com.atguigu.spring.beans.Car">
				<constructor-arg value="DaZhong"
					type="java.lang.String"></constructor-arg>
				<constructor-arg value="beijing"
					type="java.lang.String"></constructor-arg>
				<constructor-arg value="200000" type="double"></constructor-arg>
			</bean>
		</property>
	</bean>

执行main,的结果:

Person [name=zhangsan, age=26, car=Car [brand=DaZhong, corp=beijing, price=200000.0, maxSpeed=0]]

当然了,上面的例子Bean是用property注入值的,还可以用构造器注入,首先,在Person中添加构造器,然后在xml中用构造器注入内部Bean:

在Person中加入构造器:

	public Person(String name, int age, Car car) {
		super();
		this.name = name;
		this.age = age;
		this.car = car;
	}

在xml中用构造器注入:

	<bean id="person1" class="com.atguigu.spring.beans.Person">
		<constructor-arg value="zhangsan"></constructor-arg>
		<constructor-arg value="26"></constructor-arg>
		<constructor-arg ref="car1"></constructor-arg>
	</bean>

三、null值和级联属性

使用专门的<null/>元素标签为bean的字符串或者其他对象类型的属性注入null值。

和struts和hibernate等其他框架一样,Spring支持级联属性的配置。

赋值null:

	<!-- 用<null/>元素赋值null值 -->
	<bean id="person3" class="com.atguigu.spring.beans.Person">
		<constructor-arg value="zhangsan"></constructor-arg>
		<constructor-arg value="26"></constructor-arg>
		<!-- 赋值null值 -->
		<constructor-arg><null/></constructor-arg>
	</bean>

级联属性赋值(为级联属性赋值的时候,注意要先给属性初始化,才能为级联属性赋值,否则会有异常):

	<!-- 为级联属性赋值,注意属性先要初始化之后才可以为级联属性赋值,否则会有异常。 -->
	<bean id="person4" class="com.atguigu.spring.beans.Person">
		<constructor-arg value="zhangsan"></constructor-arg>
		<constructor-arg value="26"></constructor-arg>
		<constructor-arg ref="car"></constructor-arg>
		<property name="car.maxSpeed" value="240"></property>
	</bean>

四、集合属性

  1. 在Spring可以通过一组内置的xml标签(例如:<list>/<set>/<map>)来配置集合属性;
  2. 配置java.util.List类型的属性,需要指定<list>标签,在标签中包含一些元素;这些标签可以通过<value>指定简单的常用之,通过<ref>指定对其他bean的引用;通过<bean>指定内置bean的定义;通过<null/>指定空元素;甚至可以内嵌其他集合。
  3. 数组的定义和list一样,都要使用<List>;
  4. 配置java.util.set需要使用<set>标签,定义元素的方法与list一样;
  5. java.util.Map通过<map>标签定义,<map>标签里面可以使用多个<entry>作为字标签,每个条目包含一个主键和一个值;
  6. 必须要在<key>标签中定义主键;
  7. 因为主键和值的类型没有限制,所以可以只有的为他们指定<value>、<ref>、<bean>、<null>元素;
  8. 可以将map的键和值作为<entry>的属性定义;简单常量使用key和value来定义;bean的引用通过key-ref和value-ref属性定义;
  9. 使用<props>定义java.util.Properties,该标签使用多个<prop>作为子标签,每个<prop>标签必须定义key属性;
  • 用<list>标签注入属性值的样例

新建Person类:

public class Person {
	private String name;
	private int age;
	private List<Car> 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 + "]";
	}
	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;
	}
	
	
}

新建Car类:

public class Car {
	private String brand;
	private String corp;
	private double price;
	private int maxSpeed;
	
	public Car() {
		super();
	}
	
	public Car(String brand, String corp, double price, int maxSpeed) {
		super();
		this.brand = brand;
		this.corp = corp;
		this.price = price;
		this.maxSpeed = maxSpeed;
	}
	
	@Override
	public String toString() {
		return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]";
	}
	
	
}

xml设置bean:

	<!-- first car1 -->
	<bean id="newcar1"
		class="com.atguigu.spring.beans.collections.Car">
		<constructor-arg value="dazhong" index="0"></constructor-arg>
		<constructor-arg value="gansu" index="1"></constructor-arg>
		<constructor-arg value="120000.00" index="2"></constructor-arg>
		<constructor-arg value="240" index="3"></constructor-arg>
	</bean>

	<!-- secord car1 -->
	<bean id="newcar2"
		class="com.atguigu.spring.beans.collections.Car">
		<constructor-arg value="changan" index="0"></constructor-arg>
		<constructor-arg value="gansu" index="1"></constructor-arg>
		<constructor-arg value="150000.00" index="2"></constructor-arg>
		<constructor-arg value="240" index="3"></constructor-arg>
	</bean>
	<!-- 给list注入值 -->
	<bean id="newPerson"
		class="com.atguigu.spring.beans.collections.Person">
		<property name="name" value="zhangsan"></property>
		<property name="age" value="12"></property>
		<property name="cars">
			<list>
				<ref bean="newcar1" />
				<ref bean="newcar1" />
				<bean class="com.atguigu.spring.beans.collections.Car">
				<constructor-arg value="aodi"></constructor-arg>
				<constructor-arg value="changan"></constructor-arg>
				<constructor-arg value="200000" type="double"></constructor-arg>
				<constructor-arg value="180" type="int"></constructor-arg>
				</bean>
			</list>
		</property>
	</bean>

main执行:

	private void testLists() {
		ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContext.xml");
		Person person = (Person) cxt.getBean("newPerson");
		System.out.println("person= " + person);
	}

执行结果:

person= Person [name=zhangsan, age=12, cars=[Car [brand=dazhong, corp=gansu, price=120000.0, maxSpeed=240], Car [brand=dazhong, corp=gansu, price=120000.0, maxSpeed=240], Car [brand=aodi, corp=changan, price=200000.0, maxSpeed=180]]]
  • 注入Map类属性值:

使用map节点及map的entry子节点配置Map类型的成员变量。

newPerson类:

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 + "]";
	}
}

car类:

public class Car {
	private String brand;
	private String corp;
	private double price;
	private int maxSpeed;
	
	public Car() {
		super();
	}
	
	public Car(String brand, String corp, double price, int maxSpeed) {
		super();
		this.brand = brand;
		this.corp = corp;
		this.price = price;
		this.maxSpeed = maxSpeed;
	}
	
	@Override
	public String toString() {
		return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price + ", maxSpeed=" + maxSpeed + "]";
	}
	
	
}

xml:

	<!-- 配置map属性值 -->
	<bean id="newpersonmap"
		class="com.atguigu.spring.beans.collections.NewPerson">
		<property name="name" value="Rose"></property>
		<property name="age" value="28"></property>
		<property name="cars">
			<map>
				<entry key="AA" value-ref="newcar1"></entry>
				<entry key="BB" value-ref="newcar2"></entry>
			</map>
		</property>
	</bean>

main:

	private void testMaps() {
		ApplicationContext cxt=new ClassPathXmlApplicationContext("applicationContext.xml");
		NewPerson newperson=(NewPerson) cxt.getBean("newpersonmap");
		System.out.println("newperson= "+newperson);
	}

执行结果:

newperson= NewPerson [name=Rose, age=28, cars={AA=Car [brand=dazhong, corp=gansu, price=120000.0, maxSpeed=240], BB=Car [brand=changan, corp=gansu, price=150000.0, maxSpeed=240]}]
  • 定义java.util.Properties

使用<props>定义java.util.Properties,改标签使用多个<prop>作为子标签,每个<prop>标签必须定义key值。

写一个注入properties的例子:

新建一个DataSource类:

import java.util.Properties;

public class DataSource {
	private Properties properties;

	public Properties getProperties() {
		return properties;
	}

	public void setProperties(Properties properties) {
		this.properties = properties;
	}

	@Override
	public String toString() {
		return "DataSource [properties=" + properties + "]";
	}

}

XML注入方法:

	<!-- 配置properties的属性值 -->
	<bean id="properties"
		class="com.atguigu.spring.beans.collections.DataSource">
		<property name="properties">
			<props>
				<prop key="user">root</prop>
				<prop key="password">123</prop>
				<prop key="jdbcUrl">jdbc:mysql:///test</prop>
				<prop key="driverClass">com.mysql.jdbc.Driver</prop>
			</props>
		</property>

	</bean>

main方法执行:


	public static void main(String[] args) {
		// TODO Auto-generated method stub
		ApplicationContext cxt=new ClassPathXmlApplicationContext("applicationContext.xml");
		Main m = new Main();
		m.testProperties(cxt);

	}
	/**
	 * 
	 * @param cxt
	 */
	private void testProperties(ApplicationContext cxt) {
		DataSource ds=(DataSource) cxt.getBean("properties");
		System.out.println("ds= "+ds);

	}

执行结果:

ds= DataSource [properties={driverClass=com.mysql.jdbc.Driver, user=root, password=123, jdbcUrl=jdbc:mysql:///test}]

五、使用utility scheme定义集合

  1. 使用基本的集合标签定义集合的时候,不能讲集合作为独立的bean处理,导致其他bean无法引用该集合,所以无法在不同的bean之间共享集合。
  2. 可以使用util schema里面的集合标签定义独立的集合Bean,需要注意的是,必须在<beans>根元素里添加util schema定义。

xml代码:

	<!-- 配置单例的集合Bean,以供多个bean进行引用,需要导入util命名空间 -->
	<util:list id="cars111">
		<ref bean="newcar1" />
		<ref bean="newcar2" />
	</util:list>
	
	<bean id="person4"
		class="com.atguigu.spring.beans.collections.Person">
		<property name="name" value="Jack"></property>
		<property name="age" value="28"></property>
		<property name="cars" ref="cars111"></property>
	</bean>

六、使用P命名空间

  1. 问了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息;
  2. Spring从2.5版本开始引入了一个新的P空间,可以通过<bean>元素属性的方式配置Bean的属性;
  3. 使用P命名空间后,基于XML的配置方式将进一步简化;

XML样例:

	<!-- 通过p命名空间为bean的属性赋值,需要先导入P命名空间,相对于传统的配置方式更加的简洁 -->
	<bean id="personP" class="com.atguigu.spring.beans.collections.Person" p:age="30"
	p:name="Queen" p:cars-ref="cars">
	</bean>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值