您的位置:首页 > 编程语言 > Java开发

Spring学习之——依赖关系和配置细节(一)

2013-07-20 23:07 363 查看
这一次的学习主要是对配置的一些特殊属性进行了解和使用。

首先我们要了解的第一个属性就是idref,在前面的学习中我们已经接触到ref这个属性,那么idref和ref这两个属性有什么区别呢,事实上它们两个虽然长得很相似但是却不怎么相干,ref这个属性我们通过前面的学习已经知道,它的作用就是用来引用一个bean的实例用来实现依赖注入的功能,而idref则是用来引用bean的名字的注意是名字而不是实例,一个字符串而已。按照官方文档的说法就是idref是用来将容器中其他bean的id传给<constructor-arg/> 或 <property/> 元素。然后Spring容器可以在工程部署的时校验引用的名字是否存在,其实就是检查bean是不是真的有,降低工程上线运行时的风险。这里面还有一个属性local,配合idref使用更加有效,它可以将校验提前到书写配置的时候,而不必等到工程部署时。其实在我们一般的开发过程中很少用这个属性,但对一些要求比较高的项目而言这个功能还是有一定意义的,毕竟软件开发中问题的及早暴露,能最有效避免掉出现更大麻烦的可能。

我们这里还是先通过一个小程序,来演示一些这个属性的作用。

定义一个TargetBean类,可以没有属性

然后定义一个ClientBean类,如下:

public class ClientBean {

private String tbean;

public String getTbean() {
return tbean;
}
public void setTbean(String tbean) {
this.tbean = tbean;
}
}

配置文件bean.xml

<bean id="TargetBean" class="cn.com.spring.injection.bean.TargetBean"/>
<bean id="ClientBean" class="cn.com.spring.injection.bean.ClientBean">
<property name="tbean"><idref bean="TargetBean"/></property>
</bean>


使用Junit测试程序如下:

public class TestUtils extends TestCase {
private ApplicationContext actx = new FileSystemXmlApplicationContext("bean.xml");

@Test
public void test(){
ClientBean exampleBean = (ClientBean)actx.getBean("ClientBean");
System.out.println(exampleBean.getTbean());
}
}


运行结果

TargetBean

修改配置文件bean.xml

将TargetBean的配置去掉

然后再次运行,结果失败

再次修改配置文件bean.xml如下

<idref local="TargetBean"/>

发现配置文件报错

这里由于是java工程,就没有部署的步骤,但是通过最后一次的修改可以发现,Spring已经检查到idref引用的bean名字不存在并报错了。

下面我们来学习一下ref这个标签,ref有三个属性,bean,local,parent

我们前面的章节的学习已经接触到ref这个标签了,同时使用了其bean属性,其实很简单bean属性就是要引用的Bean的id名称,下面来说介绍一下它另外两个属性local,parent。

bean的使用范围比较广,使用条件比较弱,几乎在任何情况下都可以使用,属于通吃型的。

local的使用就受点限制,它所引用的bean必须是在当前文件中定义的否则会报错,所以在配置不复杂的情况下最好是用这个,因为它能帮

助你提前校验配置书写是否正确。bean属性则不受这个限制所以Spring容器也就无法事先去校验你书写的配置是否正确。

parent的使用条件比较强,它只能指定位于当前容器的父容器中定义的对象引用,所以这个属性使用就比较少。这里提到了一个父容器的慨念在下面的示例程序中将会有所体现。

下面我改造一下上面的小程序

TargetBean.java

public class TargetBean {

private String name;
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}
}

ClientBean.java

public class ClientBean {

private TargetBean tbean;

public TargetBean getTbean() {
return tbean;
}
public void setTbean(TargetBean tbean) {
this.tbean = tbean;
}
}


配置文件

<bean id="TargetBean" class="cn.com.spring.injection.bean.TargetBean">
<property name="name" value="targetBean"/>
</bean>
<bean id="ClientBean" class="cn.com.spring.injection.bean.ClientBean">
<property name="tbean"><ref bean="TargetBean"/></property>
</bean>

测试程序:

public void test1(){
ClientBean exampleBean = (ClientBean)actx.getBean("ClientBean");
System.out.println(exampleBean.getTbean().getName());
}


运行结果:

targetBean

下面我们修改配置文件,将ref的bean属性修改为local后,再次运行测试程序和上次一样,说明在目前这种配置情况下

这两个属性是几乎没什么区别

下面我们将配置文件分成两个bean1.xml和bean.xml

bean1.xml配置TargetBean

<bean id="TargetBean" class="cn.com.spring.injection.bean.TargetBean">
<property name="name" value="targetBean"/>
</bean>


bean.xml配置ClientBean

<import resource="bean1.xml"/>
<bean id="ClientBean" class="cn.com.spring.injection.bean.ClientBean">
<property name="tbean"><ref bean="TargetBean"/></property>
</bean>


执行测试程序发现结果仍然没有问题,但是此时如果将ref的bean改为local,xml文件就会报错,这也验证了local属性的使用条件,所以在同一个配置文件里使用local确实是比bean更好的选择,但是一般在项目开发中配置文件通常是复杂的并且也不只是一个,因此如果对Spring玩的不是很转还是使用bean吧。

下面再来演示一下parent属性,这个玩起来有点麻烦,我们依然是对上面的示例程序进行改造

TargetBean.java不变

ClientBean.java如下

public class ClientBean {
private TargetBean tb;
private String flag;

public TargetBean getTb() {
return tb;
}
public void setTb(TargetBean tb) {
this.tb = tb;
}
public String getFlag() {
return flag;
}
public void setFlag(String flag) {
this.flag = flag;
}

}


配置文件还是要使用两个我们这里选bean1.xml为父容器,bean.xml为子容器

bean1.xml

<bean id="TargetBean" class="cn.com.spring.injection.bean.TargetBean">
<property name="name" value="targetBeanChild"/>
</bean>
<bean id="TargetBeanParent" class="cn.com.spring.injection.bean.TargetBean">
<property name="name" value="targetBeanParent"/>
</bean>


bean.xml

<bean id="TargetBean" class="cn.com.spring.injection.bean.ClientBean">
<property name="tb"><ref parent="TargetBean"/></property>
<property name="flag" value="clientBean"/>
</bean>


测试程序如下:

public class TestUtils extends TestCase {
private ApplicationContext parent = new FileSystemXmlApplicationContext("bean1.xml");
private ApplicationContext child = new FileSystemXmlApplicationContext(new String[]{"bean.xml"},parent);

@Test
public void test1(){
TargetBean tbean = (TargetBean)parent.getBean("TargetBean");
TargetBean tbean1 = (TargetBean)child.getBean("TargetBeanParent");
ClientBean exampleBean = (ClientBean)child.getBean("TargetBean");
System.out.println(tbean.getName());
System.out.println(tbean1.getName());
System.out.println(exampleBean.getTb().getName());
System.out.println(exampleBean.getFlag());
System.out.println(tbean.getName());
}
}


这里注意一下父容器和子容器的设定是通过程序进行的。

运行一下结果如下:

targetBeanChild

targetBeanParent

targetBeanChild

clientBean

targetBeanChild

这里面要注意的就只有两点,一是父容器和子容器是由程序设定的,二是两个配置文件的联系如果使用parent标签bean属性id要和父容器的相同
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: