现在的位置: 首页 > 综合 > 正文

spring学习笔记(持续更新)

2013年02月25日 ⁄ 综合 ⁄ 共 19787字 ⁄ 字号 评论关闭
文章目录

 1.Spring的核心机制

依赖注入:相当于控制反转,spring中创建被调用者的工作不再由调用者完成,称为控制反转,创建被调用者实例的工作由spring容器完成,然后注入调用者,称为依赖注入。

11设值注入,依赖注入

111设值注入

需要setter方法

Xml文件里

1.1.2 构造注入

构造注入需要带参数的构造器。

Xml文件里

1.1.3两者比较

设置注入优点:

² 与传统的javabean的写法更相似,开发人员容易了解接受。通过setter方法设置依赖关系显得更加直观自然。

² 对于复杂的依赖关系如果采用构造注入会导致构造器过于臃肿,spring创建bean实例时,需要同时实例化其依赖的全部实例,导致性能下降。

² 多参数的构造器过于笨重

构造注入优点

² 可以在构造器中决定依赖关系的注入顺序,优先依赖的优先注入。

² 对于依赖关系无需变化的bean,构造注入更有用处,所以的依赖关系都在构造器中设定,无需担心后续的代码对依赖关系的破坏

² 只有组件的创建者才能改变组件的依赖关系,对于组件调用者,依赖关系完全透明。

建议以设置注入为主,构造注入为辅,对于依赖关系无需变化的注入,尽量采用构造注入,对于其他的,采用设置注入。

Spring中的beanbeanFactory

2.1 BeanFactory接口

 BeanFactorybean工厂,用于配置、创建、管理bean的容器,也称为spring上下文。Beanbean之间的依赖关系,也由BeanFactory负责维护。

 BeanFactory通常对应org.springframework.beans.factory.BeanFactory接口。该接口为spring容器的根接口,spring中的任何容器,都直接或间接的实现该接口,该接口的四种基本方法:

² public Boolean containsBean(String
name):
判断spring容器是否包含idnamebean定义

² public Object getBean(String
name):
返回容器中idnamebean

² public Object getBeans(String
name ,Class requiredType):
返回容器中idname,并且类型requiredTypebean.

² Public Class getType(String
name):
返回容器中idnamebean的类型。

 

BeanFactory的实现方法:通常使用

org.springframework.beans.factory.xml.xmlBeanFactory类,对于J2EE而言,推荐使用ApplicationContext,其实现类

org.springframerwork.context.support.FileSystemXmlApplicationContext.

 

创建BeanFactory的实例,应该提供XML的配置文件。XML配置文件通常使用Resource对象传入,Resource接口是spring
bean
配置资源的抽象,是所有配置资源的根接口。

 实例化BeanFactory:

 

或者采用以下方法:

如果应用中有多个属性配置文件,应采用BeanFactory子接口ApplicationContext来创建BeanFactory实例,ApplicationContext的实现类:

² FileSystemXmlApplicationContext:以指定路径的xml配置文件创建

ApplicationContext

² ClassPathXmlApplicationContext:classpath路径下的xml配置文件创建

ApplicationContext

如果有多个配置文件需要加载,需采用如下方式:

Spring最简单的配置文件


2011.5.11

Springdtd部分:详细规定了spring配置文件里的合法元素,各元素出现的先后顺序,各元素里的合法子元素、合法属性。

2.2context中的bean

 配置文件中<beans>元素可以包含bean子元素,每个</bean>定义一个beanbean的两个属性:

id: beanid,唯一的标识符。

class:bean的具体实现类,不能为接口。

2.3 bean的基本行为

Beanspring容器中有两种基本行为:

² singleton:,默认为单态,程序每次请求该Idbeanspring都会返回该bean的共享实例。

² non-singletonprototype:原型,如果为该行为,程序每次请求该idbean,spring都会新建bean实例,该行为的beanBeanFactory角色相当于New的作用,spring容器不会跟踪bean的生命周期行为。通常要求web应用的控制器bean被设置为non-singleton行为,因为,每次httpServletRequest都需要启动新的action.

 

设置bean的基本行为,通过singleton属性设置,该属性值只有两个值true,false.

如:<bean id=”axe” class=”steelAxe” singleton=”false” />设置为non-singleton,如果不设置,默认为singleton.

2.4 beanjavabean

建议的bean应满足如下原则:

² 每个bean的实现类都应提供无参数的构造器

² 接受构造注入的bean,应提供相应的构造函数

² 接受设置注入的bean,应提供setter方法,不需要提供getter方法

传统javabeanspring中的bean:

² 用处不同:传统javabean更多作为值对象传递参数,springbean几乎无所不包,任何组件都可以称为bean

² 写法不同:传统javabean作为值对象,要求每个属性有gettersetter,spring中的bean只需为设值注入的属性提供setter方法

2.5 实例化bean的方法 

三种方法:

  • 普通依赖注入里的setter(设值注入)或构造注入,相当于new一个bean实例
  • BeanFactory调用某个类的静态工厂方法创建bean
  • BeanFactory调用实例工厂方法创建bean

2.5.1普通依赖注入里的setter(设值注入)或构造注入,相当于new一个bean实例

步骤:

1.        程序创建BeanFactory实例

2.        调用Dog实例类的默认构造器创建默认实例

3.        根据配置文件确定的依赖关系,先实例化依赖bean,实现注入

4.        返回完整的javaBean实例

完整代码如下:

相应结构:Being,Dog,Cat位于包shiLiHuaBean.Static,主程序位于

shiLiHuaBean.Constructor

接口Being:

package shiLiHuaBean.Static;

 

public interface Being {

public void testBeing();

}

 Dog:

package shiLiHuaBean.Static;

public class Dog implements Being{
private String msg;
public void setMsg(String msg){
	this.msg=msg;
}
	public void testBeing(){
		// TODO Auto-generated method stub
		System.out.println(msg+"爱啃骨头");
	}

}

Cat:

package shiLiHuaBean.Static;

public class Cat implements Being{
private String msg;
//设置注入须实现set方法
public void setMsg(String msg){
	this.msg=msg;
}
public void testBeing() {
	// TODO Auto-generated method stub
	System.out.println(msg+"爱吃鱼");
}
}

主程序:

package shiLiHuaBean.Constructor;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.InputStreamResource;

import shiLiHuaBean.Static.Being;

public class SpringTest {

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		// TODO Auto-generated method stub
     //实例化BeanFacotry
	InputStream is=new FileInputStream("conf.spring/shiLiHuaBeanConstructor.xml");
	InputStreamResource isr=new InputStreamResource(is);
	XmlBeanFactory factory=new XmlBeanFactory(isr);
	
	Being b1=(Being)factory.getBean("dog");
	b1.testBeing();
	
	Being b2=(Being)factory.getBean("cat");
	b2.testBeing();
	}

}

XML配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="dog" class="shiLiHuaBean.Static.Dog">
    <property name="msg">
      <value>狗,</value>
    </property>
  </bean>
    <bean id="cat" class="shiLiHuaBean.Static.Dog">
    <property name="msg">
      <value>猫,</value>
    </property>
  </bean>
</beans>

2.5.2调用某个类的静态工厂方法创建bean

   调用某个类的静态工厂方法创建bean,其中,class属性不再是该bean的类,而是调用的工厂类,factory-method属性确定创建bean的方法名。

注意:工厂方法必须是静态的,如果静态工厂方法需要传入参数,使用<constructor-arg></constructor-arg>传入。

程序如下:

静态工厂方法BeingFacotry:

package shiLiHuaBean.Static;
import shiLiHuaBean.Static.Dog;
import shiLiHuaBean.Static.Cat;
public class BeingFactory {
	/*
	 * 获取bean实例的静态工厂方法
	 * @param arg决定返回哪个实例
	 */
public static Being getBeing(String arg){
	if(arg.equalsIgnoreCase("dog")){
		return new Dog();
	}
	else{
		return new Cat();
	}
}
}

主程序:

package shiLiHuaBean.Static;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.InputStreamResource;

public class SpringTest {

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		// TODO Auto-generated method stub
	//创建beanFactory的实例
     InputStream is=new FileInputStream("conf.spring/shiLiHuaBeanStatic.xml");
     InputStreamResource isr=new InputStreamResource(is);
     XmlBeanFactory factory=new XmlBeanFactory(isr);
     
     
     Being b1=(Being)factory.getBean("dog");
     b1.testBeing();
     
     Being b2=(Being)factory.getBean("cat");
     b2.testBeing();
	}

}

XML配置文件:

<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.sprngframework.org/dtd/spring-beans.dtd">
<beans>
<!--采用静态工厂方法产生bean实例,此时的class为产生dog的工厂类,而且必须用factory-method指定产生dog的静态方法  -->
   <bean id="dog" class="shiLiHuaBean.Static.BeingFactory" factory-method="getBeing">
   <!-- 如果方法需要传入参数,需要用constructor-arg设定 -->
       <constructor-arg>
          <value>dog</value>
       </constructor-arg>
       <!-- property用于确定普通接受依赖注入的属性 -->
       <property name="msg">
       <value>狗,</value>
       </property>
   </bean>
      <bean id="cat" class="shiLiHuaBean.Static.BeingFactory" factory-method="getBeing">
   <!-- 如果方法需要传入参数,需要用constructor-arg设定 -->
       <constructor-arg>
          <value>cat</value>
       </constructor-arg>
       <!-- property用于确定普通接受依赖注入的属性 -->
       <property name="msg">
       <value>猫,</value>
       </property>
   </bean>
</beans>

采用静态工厂方法创建实例必须提供工厂类,工厂类包含产生实例的静态方法。静态工厂方法创建的实例的使用与之前相同,区别仅在于配置文件的改变:

Ø  Class属性指定不再是bean的实现类,而是静态工厂类

Ø  必须有factory-method属性,指定产生实例的静态方法

Ø  如果静态方法有参数传入,使用<constructor-arg>传入。

2.5.3调用实例工厂方法创建bean

  通过此方法创建bean,此时bean不再有class属性,而是通过factory-bean确定创建实例的工厂类,factory-method确定产生实例的方法,该方法不为静态。

  但,工厂需要返回bean实例,即必须配置工厂bean,具体见XML配置文件

工厂代码:

package shiLiHuaBean.Factory;
import shiLiHuaBean.Static.Being;
import shiLiHuaBean.Static.Dog;
import shiLiHuaBean.Static.Cat;

public class BeingFactory {
//产生实例的方法
public Being getBeing(String arg){
	if(arg.equals("dog")){
		return new Dog();
	}
	else{
		return new Cat();
	}
}
}

 

主程序:

package shiLiHuaBean.Factory;
import shiLiHuaBean.Static.Being;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;

import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.InputStreamResource;

public class SpringTest {

	/**
	 * @param args
	 * @throws FileNotFoundException 
	 */
	public static void main(String[] args) throws FileNotFoundException {
		// TODO Auto-generated method stub
	//创建beanFactory的实例
     InputStream is=new FileInputStream("conf.spring/shiLiHuaBeanStatic.xml");
     InputStreamResource isr=new InputStreamResource(is);
     XmlBeanFactory factory=new XmlBeanFactory(isr);
     
     
     Being b1=(Being)factory.getBean("dog");
     b1.testBeing();
     
     Being b2=(Being)factory.getBean("cat");
     b2.testBeing();
	}

}

 

XML配置文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<!-- 实例工厂方法创建bean,必须配置工厂bean -->
  <bean id="BeingFactory" class="shiLiHuaBean.Factory.BeingFactory" />
<!-- 实例工厂方法创建bean,需要指定工厂bean的id属性,用factory-bean指定,factory-method用于指定产生bean实例的方法 -->
  <bean id="dog" factory-bean="BeingFactory" factory-method="getBeing">
 <!-- constructor-arg用于指定方法需要传入的参数 -->
       <constructor-arg>
          <value>dog</value>
       </constructor-arg>
 <!-- property属性用于指定普通依赖注入的属性 -->
       <property name="msg">
          <value>狗,</value>
       </property>
   </bean>
   
   <bean id="cat" factory-bean="BeingFactory" factory-method="getBeing">
     <constructor-arg>
        <value>cat</value>
     </constructor-arg>
     <property name="msg">
        <value>猫,</value>
     </property>  
   </bean>

</beans>

调用实例工厂方法创建bean,与调用静态方法创建bean的用法相似,

区别如下:

  • 调用实例工厂方法创建bean,必须将实例工厂配置成bean实例,而静态工厂方法创建bean,无需配置工厂bean
  • 调用实例工厂方法创建bean,必须使用factory-bean指定工厂bean,而静态工厂方法创建bean,只需使用class指定静态工厂类

相同之处:

  • 都需用factory-method指定产生bean的工厂方法
  • 工厂方法如果需要参数,运用<constructor-arg>传入
  • 其他依赖注入属性,都使用<property>元素确定参数值

2.6 bean特性的深入

2.6.1 bean的高级属性、合作者

Bean里的依赖通常表现为如下两种方式:

  1. 通过property属性指定
  2. 通过constructor-arg属性指定

Spring 在实例化beanfactory 时,会检验bean的配置,包括:

  • Bean引用的合作者指向一个合法bean
  • 对于singleton行为,并被设置pre-instantiated的bean,spring在创建beanFactory时,同时实例化bean;实例化bean时,也会将它所依赖的bean一起实例化

BeanFactory与ApplicationContext实例化容器中bean的时机不同:前者等到程序需要时才创建,后者在加载ApplicationContext时会自动实例化容器中的全部bean。前者的机制可能会导致配置错误发现的延迟,会给系统带来不确定的危险。而ApplicationContext则默认预实例化singleton-bean。后者比前者预实例化过程时间和内存开销大,但可以在ApplicationContext创建时候找出配置错误。

当然,可以通过设置singleton bean的lazy-load属性为true,可以改变ApplicationContext的默认行为。Bean不会跟随ApplicationContext实例化,Bean依赖通常可以接受如下元素指定值

  •  value
  •  ref
  •  bean
  •  list, set,map,props

2.6.1.1 value元素

 Value元素用于确定字符串参数,参数可以通过PropertyEditors将string转换为所需的参数类型。基本数据类型可以正常转换。

ExampleBean.java

package valueProperty;

public class ExampleBean {
private int interProperty;
private double doubleProperty;

public ExampleBean(){
	
}
public int getInterProperty() {
	return interProperty;
}
public void setInterProperty(int interProperty) {
	this.interProperty = interProperty;
}
public double getDoubleProperty() {
	return doubleProperty;
}
public void setDoubleProperty(double doubleProperty) {
	this.doubleProperty = doubleProperty;
}

public void test(){
	System.out.println(interProperty);
	System.out.println(doubleProperty);
}
}

主程序springtest.java

package valueProperty;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class SpringTest {
public static void main(String[] args){
	ApplicationContext ctx = new FileSystemXmlApplicationContext("conf.spring/valueProperty.xml");
	ExampleBean eb=(ExampleBean) ctx.getBean("exampleBean");
	eb.test();
}
}

配置文件valueProperty.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN/EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="exampleBean" class="valueProperty.ExampleBean">
    <property name="interProperty">
      <value>1</value>
    </property>
    <property name="doubleProperty">
      <value>2.3</value>
    </property>
  </bean>
</beans>

执行结果:

1

2.3

 

Value元素注意用于传入字符串参数,基本数据类型。也可以传入合作者bean,但不推荐使用value.value元素的值可以指定为空,指定空属性通过<null/>元素。

<bean class=”ExampleBean”>
   <property name=”email”>
    <value></value>
   </property>
</bean>

<bean class=”ExampleBean”>
  <property name=”email”>
   <null/>
   </property>
</bean>

2.6.1.2 ref元素

ref:用于指定属性值为spring容器中的其他bean,推荐采用ref元素指定而不是value元素

<bean id=”steelAxe” class=”SteelAxe”>
<bean id=”chinese” class=”Chinese”>
   <property name=”axe”>
     <ref local=”stellAxe” />
</property>
</bean>
</bean>

与下面的配置文件效果一样

<bean id=”steelAxe” class=”SteelAxe”>
<bean id=”chinese” class=”Chinese”>
   <property name=”axe”>
     <value>steelAxe</value>
</property>
</bean>
</bean>

第一种比第二种更好的原因:使用ref标记,可以让spring在部署时验证依赖的bean是否真正存在,第二种,steelAxe属性值仅在创建bean实例时验证,会导致错误的延迟,而且还有额外的类型转换开销,因此,合作者bean属性的传入,推荐采用ref指定。Ref通常有两个属性:

Ø  bean: 用于确定不再同一个配置文件中的bean

Ø  local:用于确定在同一个XML配置文件中的其他bean,并且local属性只能是其它bean的id属性

ref是local的更严格,并能防止出错的形式,Local则是bean更严格,并能防止出场的形式。

2.6.1.3 bean元素

  Bean元素用于定义嵌套bean,而不是在spring中已经存在的bean.嵌套bean只对外部bean有效,没有id属性,不能被spring容器访问,提供了程序内聚性

<bean id=”Chinese” class=”Chinese”>
   <property name=”axe”>
      <bean class=”SteelAxe” />
   </property>
</bean>

2.6.1.4 list.set.map.props元素

 list,set,map,props元素分别用于设置List,Set.,Map和Properties的属性值,分别用来为bean传入集合值,代码如下:

Axe接口

package beanYuanSu;

public interface Axe {

}

StoneAxe.java

package beanYuanSu;

public class StoneAxe {
	public StoneAxe(){
		
	}
	public String chop(){
		return "Use stoneAxe ";
	}
}

Person接口

package beanYuanSu;

public interface Person {
public void test();
}

Chinese.java

package beanYuanSu;

import java.util.List;     //一定要是java.util.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
public class Chinese implements Person{

	//系列集合属性
	private List schools=new ArrayList();
	private Map score=(Map)new HashMap();
	private Properties health=new Properties();
	private Set axes=(Set)new HashSet();
	
	public Chinese()
	{
	  System.out.println("Sprint实例化主调bean,Chinese实例....");
	}

   
	public void setSchools(List schools) {
		this.schools = (java.util.List) schools;
	}
	

	public void setScore(Map score) {
		this.score = score;
	}

	public void setAxes(Set axes) {
		this.axes = axes;
	}
    
	public void setHealth(Properties health){
		this.health=health;
	}
	public void test(){
		System.out.println(schools);
		System.out.println(score);
		System.out.println(health);
		System.out.println(axes);
	}
}

主程序

SpringTest.java

package beanYuanSu;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class SpringTest {
public static void main(String[] args){
	ApplicationContext ctx=new FileSystemXmlApplicationContext("conf.spring/beanYuanSu.xml");
	Person p=(Person)ctx.getBean("Chinese");
	p.test();
}
}

Xml配置文件beanYuanSu.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<!--spring配置文件的根元素  -->
<beans>
  <bean id="stoneAxe" class="beanYuanSu.StoneAxe" />
  <!--定义 chinese bean-->
  <bean id="Chinese" class="beanYuanSu.Chinese">
     <!-- 定义list属性,使用List元素 -->
      
     <property name="schools">
     <!--  list 元素里使用value确定系列值-->  
       <list>
          <value>小学</value>
          <value>中学</value>
          <value>大学</value>
          
       </list>
     </property>
  
     <!-- 定义Map属性,使用map元素 -->
     <property  name="score">
       <map>
          <!-- map属性必须是key-value对 -->
          <entry key="数学">
             <value>80</value>
          </entry>
          <entry key="英语">
             <value>90</value>
          </entry>
        </map>
     </property>
     <!-- 定义properties属性,使用props元素 -->
     <property name="health">
        <props>
           <!-- props 属性必须是key-value 对 -->
           <prop key=" 血压">正常</prop>
           <prop key="身高">175</prop>
        </props>
     </property>
     <property name="axes">
      <!-- set属性 -->
        <set>
          <value>字符串斧子</value>
          <bean class="beanYuanSu.StoneAxe"></bean>
          <ref local="stoneAxe" />
        </set>
     </property>
  </bean>
</beans>

输出结果

[小学, 中学, 大学]

{数学=80, 英语=90}

{身高=175,  血压=正常}

[字符串斧子, beanYuanSu.StoneAxe@7bd9f2, beanYuanSu.StoneAxe@121cc40]

 

 如上配置文件:set元素可以通过value,bean,ref确定值,map元素entry的值,set元素的值都可以使用如下元素。

Ø  value:确定基本数据类型值,或字符串类型值

Ø  ref:确定另一个bean为属性值

Ø  bean:确定一个嵌套bean为属性值

Ø  list,map,set,props:确定集合为属性值

2.6.2 使用depends-on强制初始化bean

 如果一个类的初始化块会使用其他bean,而此时spring总是先初始化主调bean,执行初始化时还没有实例化主调bean,被依赖bean还没实例化,使用depends-on可以在初始化主调bean之前强制一个或多个bean初始化。配置文件

<!—配置beanOne,该bean需要实例化之前,使用manager bean ,使用depends-on强制manager bean在初始化beanOne之前实例化-->
<bean id=”beanOne” class=”BeanOne” depends-on=”manager”>
<property  name=”manager”>
  <ref local=”manager” />
</property>
</bean>
<bean id=”manager” class=”ManagerBean” />

 

2.6.3 自动装配

 即spring可以自动装配bean与bean之间的关系,无需使用ref显式指定依赖bean。由beanFactory检查XML配置文件内容,为主调bean注入依赖关系。它可以具体 指定到每个bean,可让某个bean使用自动装配,某些不使用。

  可以减少配置文件的工作量,但降低了依赖关系的透明性和清晰性。通过autowire属性可以接受如下5种值。

  •  no: 不使用自动装配。Bean依赖必须通过ref元素定义。这是默认的配置,在较大的部署环境中不鼓励改变这个配置,指定合作者能够得到更多的控制和清晰性。
  • byName:根据属性名自动装配。BeanFactory查找容器中全部bean,找出其中ID属性与属性名同名的bean
  • byType:根据属性类型自动装配。BeanFactory查找容器中全部bean,如果正好有一个与依赖属性类型相同的bean,自动装配这个属性,如果有多个,抛出异常。如果没有,什么都不会发生,属性不会被设置。如果需要无法自动装配是抛出异常,设置dependency-check=”object”.
  • constructor:与byType类似,区别是用于构造注入的参数,如果beanFactory中,不是恰好有一个bean与构造器参数相同类型,产生致命错误
  • autodetect:beanFactory根据bean内部结构,决定使用constructor或byType,如果找到一个默认的构造函数,那么就会应用byType.

2.6.3.1 byName

配置文件

<beans>
  <bean id=”chinese” class=”Chinese” autowire=”byName” />
  <bean id=”gundog” class=”GunDog”>
     <property name=”name”>
       <value>wangwang</value>
</property>
   </bean>
</beans>

上面的配置文件,要求Chinese类中有如下方法:

/*
依赖关系必须的setter方法,因为需要通过名字自动装配,因此setter方法名必须是set+bean名。Bean名首字母大写
*/
public void setGunDong(Dog dog){
this.dog=dog;
}

2.6.3.2 byType

 配置文件:

<beans>
  <bean id=”chinese” class=”Chinese” autowire=”byType” />
  <bean id=”gundog” class=”GunDog”>
     <property name=”name”>
       <value>wangwang</value>
</property>
   </bean>
</beans>

上面的配置文件,要求Chinese类中有如下方法:

/*
依赖关系必须的setter方法,因为需要通过类型自动装配,因此setter方法的参数类型与容器的bean的类型相同,程序中的GunDog实现Dog接口
*/
public void setGunDong(Dog dog){
this.dog=dog;
}

如果出现以下配置文件

<beans>
  <bean id=”chinese” class=”Chinese” autowire=”byType” />
  <bean id=”gundog” class=”GunDog”>
     <property name=”name”>
       <value>wangwang</value>
</property>
   </bean>
<bean id=petdog” class=”PetDog”>
     <property name=”name”>
       <value>ohoh</value>
</property>
   </bean>
</beans>

此时spring无法实现自动装配,容器中有两个类型为Dog的bean,spring无法确定应为chinese注入那个bean。

当一个bean既使用自动装配依赖,又使用ref显式指定依赖,则显式指定依赖覆盖自动装配。

<beans>
  <bean id=”chinese” class=”Chinese” autowire=”byType” >
<property name=”GunDog”>\
   <ref local=”GunDog”>
 </property>
   </bean>
  <bean id=”gundog” class=”GunDog”>
     <property name=”name”>
       <value>wangwang</value>
</property>
   </bean>
   
<bean id=petdog” class=”PetDog”>
     <property name=”name”>
       <value>ohoh</value>
</property>
   </bean>
</beans>

此时chinese会被注入GunDog类实例,显式的ref指定依赖覆盖自动装配指定的依赖。

注:对于大型的应用,不鼓励使用自动装配。自动装配减少了配置文件的工作量,但降低了依赖关系的清晰性和透明性,依赖关系的装配依赖于源文件的属性名,导致bean与bean之间的耦合降低到代码层次,不利于高层次解耦。

 

2.6.4 依赖检查

 依赖检查可以保证bean的属性得到正确设置,但某些情况下,并不需要为bean的每个属性都设置值,或者某些属性已经有默认的值,此时采用依赖检查就会出错。  

   默认不应用依赖检查,通过dependency-check属性设置

Ø  none: 不进行依赖检查。没有指定值得bean属性仅仅是没有设值。

Ø  simple:对基本类型和集合(除了合作者bean)进行依赖检查

Ø  objects:仅对合作者bean进行依赖检查

Ø  all: 对所有进行依赖检查,包括合作者bean,基本类型和集合。

Chinese.java

package dependencyCheck;

public class Chinese {
private String name;
private int age=20;
private Axe axe;

public Axe getAxe() {
	return axe;
}
public void setAxe(Axe axe) {
	this.axe = axe;
}
public Chinese(){
	
}
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 void test(){
	System.out.println("name:"+name);
	System.out.println("age:"+age);
	axe.chop();
}

}

Axe.java

package dependencyCheck;

public class Axe {
public void chop(){
	System.out.println("斧子");
}
}

主程序springTest.java

package dependencyCheck;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;

public class SpringTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
     ApplicationContext ctx=new FileSystemXmlApplicationContext("conf.spring/dependencyCheck.xml");
     Chinese c=(Chinese) ctx.getBean("Chinese");
     c.test();
     
	}

}

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
  <bean id="axe" class="dependencyCheck.Axe" />
 <bean id="Chinese" class="dependencyCheck.Chinese" dependency-check="objects">
     <property name="name">
         <value>ttt</value>
      </property>
      <property name="axe">
         <ref local="axe" />
      </property>
 </bean>
</beans>

此时不会出错,如果改成dependency-check="all",会出错。

 

 

 

抱歉!评论已关闭.