Spring食行记之属性配置细节

1.【属性值注入还可以用value节点进行注入】

2.【字面值】

(1)字面值:可用字符串表示的值,可以通过<value>元素标签或value属性进行注入。

(2)基本数据类型及其封装类、String等类型都可以采取字面值注入的方式。

(3)若字面值中包含特殊字符,可以使用<![CDATA[]]>把字符值包裹起来

举栗子:

运行结果:

【3.引用其他的bean】

 (1)组成应用程序的Bean经常需要相互协作以完成应用程序的功能。要使Bean能够相互访问,就必须在Bean配置文件中指定对Bean的引用。

(2)在Bean的配置文件中,可以通过<ref>元素或者ref属性为Bean的属性或者构造器参数指定对Bean的引用。

<ref>元素:

ref属性:

(3)也可以在属性或构造器里包含Bean的声明,这样的Bean称为内部Bean。

当Bean实例仅仅给一个特定的属性使用时,可以将其声明为内部Bean。内部Bean声明直接包含在<property>或<constructor-arg>元素里,不需要设置任何id或name属性。

内部Bean不能使用在任何地方。

1         <!-- 内部bean ,不能被外部引用,只能在内部使用-->
2         <property name="car">
3             <bean class="com.hk.beans.Car">
4                 <constructor-arg value="Ford"></constructor-arg>
5                 <constructor-arg value="ChangAn"></constructor-arg>
6                 <constructor-arg value="200000" type="double"></constructor-arg>
7             </bean>
8         </property>

【中途解决bug】

 1 九月 05, 2018 2:48:22 下午 org.springframework.context.support.ClassPathXmlApplicationContext refresh
 2 警告: Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'person2' defined in class path resource [applicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 2: Could not convert argument value of type [java.lang.String] to required type [com.hk.beans.Car]: Failed to convert value of type [java.lang.String] to required type [com.hk.beans.Car]; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.hk.beans.Car]: no matching editors or conversion strategy found
 3 Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'person2' defined in class path resource [applicationContext.xml]: Unsatisfied dependency expressed through constructor parameter 2: Could not convert argument value of type [java.lang.String] to required type [com.hk.beans.Car]: Failed to convert value of type [java.lang.String] to required type [com.hk.beans.Car]; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.hk.beans.Car]: no matching editors or conversion strategy found
 4     at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
 5     at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
 6     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1148)
 7     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1051)
 8     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
 9     at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
10     at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
11     at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
12     at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
13     at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
14     at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
15     at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
16     at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
17     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
18     at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
19     at com.hk.beans.Main.main(Main.java:20)

代码错误定位到Main.java中的:

1 ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

翻译错误:

 1 ClassPathXmlApplicationContext刷新
 2 警告:上下文初始化期间遇到的例外——取消刷新尝试:org.springframework.beans.factory。不满足的依赖异常:在类路径资源applicationContext中定义的名称“person2”错误创建bean。xml:通过构造器参数2表达不满意的依赖性:不能转换类型java.lang的参数值。字符串到需要的类型com.hk.bean。Car:未能转换类型java.lang的值。字符串到所需的类型com.hk.beans.car;嵌套异常是java.lang。非法状态例外:不能转换类型java.lang的值。字符串到需要的类型com.hk.bean。Car:没有匹配的编辑器或转换策略
 3 线程“main”。springframework.beans.factory。不满足的依赖异常:在类路径资源applicationContext中定义的名称“person2”错误创建bean。xml:通过构造器参数2表达不满意的依赖性:不能转换类型java.lang的参数值。字符串到需要的类型com.hk.bean。Car:未能转换类型java.lang的值。字符串到所需的类型com.hk.beans.car;嵌套异常是java.lang。非法状态例外:不能转换类型java.lang的值。字符串到需要的类型com.hk.bean。Car:没有匹配的编辑器或转换策略
 4 org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
 5 org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:189)
 6 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1148)
 7 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1051)
 8 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:510)
 9 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482)
10 在1.美元org.springframework.beans.factory.support.AbstractBeanFactory getobject(AbstractBeanFactory.java:306)
11 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
12 org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
13 org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
14 org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751)
15 org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:861)
16 org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:541)
17 在org.springframework.context.support.ClassPathXmlApplicationContext。< init >(ClassPathXmlApplicationContext.java:139)
18 在org.springframework.context.support.ClassPathXmlApplicationContext。< init >(ClassPathXmlApplicationContext.java:83)
19 com.hk.beans.Main.main(Main.java:20)

最后发现,是配置文件中的一个构造器属性错误:

解决:应该将value改为ref,粗心大意了 +_+。

【4.注入参数:null值和级联属性】

(1)可以用专用的<null/>元素标签为Bean的字符串或其他对象类型的属性注入null值。

测试:

1    <bean id="person2" class="com.hk.beans.Person">
2       <constructor-arg value="student" ></constructor-arg>
3       <constructor-arg value="25"></constructor-arg>
4       <!--  
5       <constructor-arg ref="car"></constructor-arg>
6       -->
7       <!-- 测试赋值null -->
8       <constructor-arg><null/></constructor-arg>
9    </bean>

运行结果:

(2)和Struts、Hibernate等框架一样,Spring支持级联属性的配置

1 <constructor-arg ref="car"></constructor-arg>
2 <!-- 为级联属性赋值 ,注意;属性需要先初始化后才可以为级联属性赋值,否则会有异常,和Struts2不同。-->
3 <property name="car.maxSpeed" value="300000"></property>

以上代码可知,先给car赋值,再给car的属性maxSpeed赋值。

问题:如果先不给car赋值,直接给maxSpeed赋值,会行的通吗?试验一下--->

 1    <bean id="person" class="com.hk.beans.Person">
 2        <property name="name" value="xskb"></property>
 3        <property name="age" value="22"></property>
 4         <!-- 内部bean ,不能被外部引用,只能在内部使用-->
 5         <!--  
 6         <property name="car">
 7             <bean class="com.hk.beans.Car">
 8                 <constructor-arg value="Ford"></constructor-arg>
 9                 <constructor-arg value="ChangAn"></constructor-arg>
10                 <constructor-arg value="200000" type="double"></constructor-arg>
11             </bean>
12         </property>
13         -->
14         <property name="car.maxSpeed" value="260"></property>
15    </bean>

上述配置文件代码,没有给car赋值,直接给car的属性maxSpeed赋值,跑一下,有bug,如下:

1 Caused by: org.springframework.beans.NullValueInNestedPathException: Invalid property 'car' of bean class [com.hk.beans.Person]: Value of nested property 'car' is null

但是,当先给car赋值,再给car的属性赋值,就没有错误了。

 1    <bean id="person" class="com.hk.beans.Person">
 2        <property name="name" value="xskb"></property>
 3        <property name="age" value="22"></property>
 4         <!-- 内部bean ,不能被外部引用,只能在内部使用--> 
 5         <property name="car">
 6             <bean class="com.hk.beans.Car">
 7                 <constructor-arg value="Ford"></constructor-arg>
 8                 <constructor-arg value="ChangAn"></constructor-arg>
 9                 <constructor-arg value="200000" type="double"></constructor-arg>
10             </bean>
11         </property>
12         <property name="car.maxSpeed" value="260"></property>
13    </bean>

运行结果:

【5.集合属性】

(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一样。

 配置java.util.List类型的属性,需要指定<list>标签,在标签里包含一些元素。这些标签可以通过<value>指定简单的常量值,通过<ref>指定对其他Bean的引用:

 1    <!-- 测试如何配置集合属性 -->
 2    <bean id="person3" class="com.hk.beans.collections.Person">
 3       <property name="name" value="Mike"></property>
 4       <property name="age" value="25"></property>
 5       <property name="cars" >
 6       <!-- 使用List节点为List类型的属性赋值 -->
 7           <list>
 8              <ref bean="car"/>
 9              <ref bean="car2"/>
10           </list>
11       </property>
12    </bean>

运行结果:

1 HelloWorld's Constructor...
2 setName:Spring
3 Person [name=Mike, age=25, cars=[Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250]]]

 通过<bean>指定内置Bean定义:

运行结果;

1 HelloWorld's Constructor...
2 setName:Spring
3 Person [name=Mike, age=25, cars=[Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250], Car [brand=Ford, corp=ChangAn, price=200000.0, maxSpeed=0]]]

(5)Java.util.Map通过<map>标签定义,<map>标签里可以使用多个<entry>作为作为子标签。每个条目包含一个键和一个值。

(6)必须在<key>标签里定义键。

(7)因为键和值的类型没有限制,所以可以自由地为它们指定<value>,<ref>,<bean>或<null>元素。

(8)可以将Map的键和值作为<entry>的属性定义:简单常量使用key和value来定义;Bean引用通过key-ref和value-ref属性定义。

 1    <!-- 配置map属性值 -->
 2    <bean id="newPerson" class="com.hk.beans.collections.NewPerson">
 3        <property name="name" value="xingxing"></property>
 4        <property name="age" value="22"></property>
 5        <property name="cars">
 6             <map>
 7                <entry key="AA" value-ref="car"></entry>
 8                <entry key="BB" value-ref="car2"></entry>
 9             </map>
10        </property>
11    </bean>

运行结果;

1 HelloWorld's Constructor...
2 setName:Spring
3 Person [name=Mike, age=25, cars=[Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250], Car [brand=Ford, corp=ChangAn, price=200000.0, maxSpeed=0]]]
4 NewPerson [name=xingxing, age=22, cars={AA=Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], BB=Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250]}]

(9)使用<props>定义java.util.Properties,该标签使用多个<prop>作为子标签。每个<prop>标签必须定义key属性。

 1    <!-- 配置properties属性值 -->
 2    <bean id="dataSource" class="com.hk.beans.collections.DataSource">
 3       <property name="properties">
 4          <props>
 5             <prop key="user">root</prop>
 6             <prop key="password">xingshengkebei</prop>
 7             <prop key="jdbcUrl">jdbc:mysql://test</prop>
 8             <prop key="driverClass">com.mysql.jdbc.Driver</prop>
 9          </props>
10       </property>
11    </bean>

运行结果:

【6.使用utility scheme定义集合】

(1)使用集合的集合标签定义集合时,不能将集合作为独立的Bean定义,导致其他Bean无法引用该集合,所以无法在不同Bean之间共享集合

(2)可以使用util scheme里的集合标签定义独立的集合Bean。需要注意的是,必须在<beans>根元素里添加util scheme定义。

导入util命名空间:

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xmlns:util="http://www.springframework.org/schema/util"
5     xsi:schemaLocation="http://www.springframework.org/schema/beans
6         http://www.springframework.org/schema/beans/spring-beans.xsd
7         http://www.springframework.org/schema/util
8         http://www.springframework.org/schema/util/spring-util-4.0.xsd">

配置文件中的代码:

 1    <!-- 配置独立的集合bean,以供多个bean进行引用 ,需要导入util命名空间-->
 2    <util:list id="cars">
 3       <ref bean="car"/>
 4       <ref bean="car2"/>
 5    </util:list>
 6    
 7    <bean id="person4" class="com.hk.beans.collections.Person">
 8        <property name="name" value="Jack"></property>
 9        <property name="age" value="29"></property>
10        <property name="cars" ref="cars"></property>
11    </bean>

运行结果:

1 HelloWorld's Constructor...
2 setName:Spring
3 Person [name=Jack, age=29, cars=[Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250]]]

【7.使用p命名空间】

(1)为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。

(2)Spring从2.5版本开始引入一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean的属性。

(3)使用p命名空间之后,基于XML的配置方式将进一步简化。

注意:要导入p命名空间:

配置文件中的代码:

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

运行结果:

1 HelloWorld's Constructor...
2 setName:Spring
3 Person [name=China, age=30, cars=[Car [brand=BWM, corp=ShangHai, price=100000.0, maxSpeed=300000], Car [brand=bieke, corp=<ShangHai**>, price=0.0, maxSpeed=250]]]

【附录】

1.怎么导入命名空间?

第一步,看左下角有个Namespaces,打开:

第二步,如图所示,按需导入即可:

有关示例的部分代码:

com.hk.beans包中:

Car.java:

 1 package com.hk.beans;
 2 
 3 public class Car {
 4     private String brand;
 5     private String corp;
 6     private double price;
 7     private int maxSpeed;
 8     
 9     public Car(String brand, String corp, double price) {
10         super();
11         this.brand = brand;
12         this.corp = corp;
13         this.price = price;
14     }
15     
16     public void setPrice(double price) {
17         this.price = price;
18     }
19 
20     public void setMaxSpeed(int maxSpeed) {
21         this.maxSpeed = maxSpeed;
22     }
23 
24     @Override
25     public String toString() {
26         return "Car [brand=" + brand + ", corp=" + corp + ", price=" + price
27                 + ", maxSpeed=" + maxSpeed + "]";
28     }
29 
30     public Car(String brand, String corp, int maxSpeed) {
31         super();
32         this.brand = brand;
33         this.corp = corp;
34         this.maxSpeed = maxSpeed;
35     }
36 }

Person.java:

 1 package com.hk.beans;
 2 
 3 public class Person {
 4     private String name;
 5     private int age;
 6     
 7     private Car car;
 8 
 9     public String getName() {
10         return name;
11     }
12 
13     public void setName(String name) {
14         this.name = name;
15     }
16 
17     public int getAge() {
18         return age;
19     }
20 
21     public void setAge(int age) {
22         this.age = age;
23     }
24 
25     public Car getCar() {
26         return car;
27     }
28 
29     public void setCar(Car car) {
30         this.car = car;
31     }
32 
33     @Override
34     public String toString() {
35         return "Person [name=" + name + ", age=" + age + ", car=" + car + "]";
36     }
37 
38     public Person() {
39         // TODO Auto-generated constructor stub
40     }
41 
42     public Person(String name, int age, Car car) {
43         super();
44         this.name = name;
45         this.age = age;
46         this.car = car;
47     }
48 
49 }

com.hk.beans.collections包中:

NewPerson.java:

 1 package com.hk.beans.collections;
 2 
 3 import java.util.Map;
 4 import com.hk.beans.Car;
 5 
 6 public class NewPerson {
 7     private String name;
 8     private int age;
 9     
10     private Map<String,Car> cars;
11 
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     public int getAge() {
21         return age;
22     }
23 
24     public void setAge(int age) {
25         this.age = age;
26     }
27 
28     public Map<String, Car> getCars() {
29         return cars;
30     }
31 
32     public void setCars(Map<String, Car> cars) {
33         this.cars = cars;
34     }
35 
36     @Override
37     public String toString() {
38         return "NewPerson [name=" + name + ", age=" + age + ", cars=" + cars
39                 + "]";
40     }
41 }

Person.java:

 1 package com.hk.beans.collections;
 2 
 3 import java.util.List;
 4 import com.hk.beans.Car;
 5 
 6 public class Person {
 7     private String name;
 8     private int age;
 9     
10     private List<Car> cars;
11 
12     public String getName() {
13         return name;
14     }
15 
16     public void setName(String name) {
17         this.name = name;
18     }
19 
20     public int getAge() {
21         return age;
22     }
23 
24     public void setAge(int age) {
25         this.age = age;
26     }
27 
28     public List<Car> getCars() {
29         return cars;
30     }
31 
32     public void setCars(List<Car> cars) {
33         this.cars = cars;
34     }
35 
36     public Person() {
37         // TODO Auto-generated constructor stub
38     }
39 
40     @Override
41     public String toString() {
42         return "Person [name=" + name + ", age=" + age + ", cars=" + cars + "]";
43     }
44 
45     public Person(String name, int age, List<Car> cars) {
46         super();
47         this.name = name;
48         this.age = age;
49         this.cars = cars;
50     }
51 }

DataSource.java:

 1 package com.hk.beans.collections;
 2 
 3 import java.util.Properties;
 4 
 5 public class DataSource {
 6     private Properties properties;
 7 
 8     public Properties getProperties() {
 9         return properties;
10     }
11 
12     public void setProperties(Properties properties) {
13         this.properties = properties;
14     }
15 
16     @Override
17     public String toString() {
18         return "DataSource [properties=" + properties + "]";
19     }
20 }

猜你喜欢

转载自www.cnblogs.com/zhzcode/p/9591622.html
今日推荐