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

Spring应用教程-3 依赖关系配置

2015-02-11 23:46 295 查看


注:组件与组件之间的耦合,采用依赖注入管理,但普通的JavaBean属性值,应直接在代码中设置。

1. 注入其他Bean的属性值

我们分析一下,Bean_A的一个属性要依赖Bean_B的一个属性值。这时应该怎么配,我们以前使用的都是通过setter方法来为Bean设置值,现在我们却要使用getter方法来获取Bean的属性值。使用我们现在的知识完全可以解决这个问题(可以先不看下面的分析,对照Spring应用教程-1的第六节:Bean的生命周期自己分析

):

①Bean_A的一个属性要依赖Bean_B的一个属性值,那么我们必须首先要获取这个Bean,要获取Bean,我就要实现BeanFactoryAware接口;

②获取Bean_B的属性值,那个属性呢?这个值必须要在外面给我们说明,从Bean生命周期中我们除了发现BeanNameAware接口可以将外面的属性名给我之外,再没有其它合适的方法了。

③返回获取的Bean_B的属性值。由于我们是在Spring配置文件中配置这个信息,一般的Bean返回的是该Bean的实例,而我们现在要的是该bean的属性值 ,这就使得我们必须实现FactoryBean接口了。

我们定义这样一个实例,习大大有一个母亲,名字叫中国,我也是,我要依赖他的母亲属性的值:

[+]view code

[b]public[/b]class Chinese {

[b]private[/b] China mother;

[b]public[/b] China getMother() {
[b]return[/b] mother;
}
[b]public[/b] void setMother(China mother) {
[b]this[/b].mother = mother;
}
}

我创建一个Chinese类,他有一个类型为China的mother。然后我们创建一个工具类,实现我们的属性值注入功能:

[+]view code

[b]public[/b]class PropertyRefConfig implements BeanFactoryAware, BeanNameAware,

FactoryBean<Object> {
[b]private[/b] BeanFactory beanFactory=null;
[b]private[/b] String property=null;

@Override
[b]public[/b] void setBeanName(String beanName) {
[b]this[/b].property=beanName;
}

@Override
[b]public[/b] void setBeanFactory(BeanFactory beanFactory) throws BeansException {
[b]this[/b].beanFactory=beanFactory;
}

@Override
[b]public[/b] Object getObject() throws Exception {
String[] paths=property.split("\\.");
Object obj=beanFactory.getBean(paths[0]);
Object tmp=obj;
Class<?> type=obj.getClass();
[b]for[/b](int i=1; i<paths.length; i++){
String pro="get"+paths[i].replace(paths[i].charAt(0), String.valueOf(paths[i].charAt(0)).toUpperCase().charAt(0));
Method method=type.getMethod(pro);
obj=method.invoke(obj);
}
[b]return[/b] tmp==obj?null:obj;
}

@Override
[b]public[/b] Class<?> getObjectType() {
// TODO Auto-generated method stub
[b]return[/b] null;
}
@Override
[b]public[/b] boolean isSingleton() {
// TODO Auto-generated method stub
[b]return[/b] false;
}
}

这个类配置为Bean后,在进行实例化并通过setter注入属性后,执行BeanNameAware接口方法(setBeanName),通过该方法我们拿到了该Bean的id属性,我们这里不是使用这个id属性获取该Bean的实例的,这个id已经失去了它本来的意义,我们是让它把我们要的数据(那个Bean的那个属性)给我们带进来。然后解析这个id,获取要获取那个Bean和该Bean的属性值。然后通过FactoryBean将该属性值返回。

然后我们配置Bean,使我的mother属性依赖习大大的mother属性



[+]view code

<bean id="china" class="smzq.China"/>

<bean id="xidada" class="smzq.Chinese">
<property name="mother" ref="china"/>
</bean>
<bean id="me" class="smzq.Chinese">
<property name="mother">
<bean id="xidada.mother" class="smzq.PropertyRefConfig"/>
</property>
</bean>

这里我们使用了嵌套Bean,它的id属性表明,我们要取xidada的mother属性。

测试:





其实这也就是PropertyPathFactoryBean的原理,不过强大的Spring将它包装的更完美了

。有了这个类,我们便可以直接使用了,不用再费神的写PropertyRefConfig了:

[+]view code

<bean id="china" class="smzq.China"/>

<bean id="xidada" class="smzq.Chinese">
<property name="mother" ref="china"/>
</bean>
<bean id="me" class="smzq.Chinese">
<property name="mother">
<bean id="xidada.mother" class="org.springframework.beans.factory.config.PropertyPathFactoryBean"/>
</property>
</bean>

这样配置便好了。查看PropertyPathFactoryBean我们发现,它也是继承了这3个接口:





2. 注入其他Bean的方法返回值

按照前面的例子,我们可以轻松的自己实现这个功能,这里就不再演示了(反正又没Spring写得好

)直接用Spring提供的类了:

通过Spring提供的MethodInvokingFactoryBean工厂Bean便可以实现这个需求:

[+]view code

<bean id="china" class="smzq.China"/>

<bean id="xidada" class="smzq.Chinese">
<property name="mother" ref="china"/>
</bean>
<bean id="me" class="smzq.Chinese">
<property name="mother">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="xidada"/>
<property name="targetMethod" value="getMother"/>
</bean>
</property>
</bean>

其中:

targetObject属性表明要调用那个Bean中的方法;

targetMethod属性表明要调用那个方法。

上面我们调用的方法是实例方法,如果我们调用的是一个静态方法时,就无需使用targetObject属性了,使用targetClass属性即可。

我们都知道,Java允许方法重载,那么我们上面这样的调用遇见重载方法时是不是会出现问题呢?如果方法有参数,我们怎么传入?

我们上面这种方法实际上是调用对应方法的无参版本,如果方法有参数,则使用arguments 属性来传入:

[+]view code

<bean id="commonpeople" class="smzq.People">

<property name="mustobserve">
<bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject" ref="chairman"/>
<property name="targetMethod" value="enacted_laws"/>
<property name="arguments">
<list>
<value>宪法</value>
<ref bean="where"/>
</list>
</property>
</bean>
</property>
</bean>

如果对给集合类型注入值不太熟悉的话,可以参考Spring应用教程-1的7.2节
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: