注:组件与组件之间的耦合,采用依赖注入管理,但普通的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

public class Chinese {

    private China mother;
 
    public China getMother() {
        return mother;
    }
    public void setMother(China mother) {
        this.mother = mother;
    }

}

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

[+]view code

public class PropertyRefConfig implements BeanFactoryAware, BeanNameAware,

        FactoryBean<Object> {
    private BeanFactory beanFactory=null;
    private String property=null;
 
    @Override
    public void setBeanName(String beanName) {
        this.property=beanName;
    }
 
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory=beanFactory;
    }
 
    @Override
    public Object getObject() throws Exception {
        String[] paths=property.split("\\.");
        Object obj=beanFactory.getBean(paths[0]);
        Object tmp=obj;
        Class<?> type=obj.getClass();
        for(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);
        }
        return tmp==obj?null:obj;
    }
 
    @Override
    public Class<?> getObjectType() {
        // TODO Auto-generated method stub
        return null;
    }
    @Override
    public boolean isSingleton() {
        // TODO Auto-generated method stub
        return 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节

Spring应用教程-3 依赖关系配置的更多相关文章

  1. Spring框架学习之高级依赖关系配置(一)

    上篇文章我们对Spring做了初步的学习,了解了基本的依赖注入思想.学会简单的配置bean.能够使用Spring容器管理我们的bean实例等.但这还只是相对较浅显的内容,本篇将介绍bean的相关更高级 ...

  2. Spring IOC、对象依赖关系

    Spring IOC.对象依赖关系   2016-09-21 01:36 414人阅读 评论(0) 收藏 举报 本文章已收录于: 版权声明:本文为博主原创文章,未经博主允许不得转载. 引入 Strut ...

  3. 微服务下 Spring Boot Maven 工程依赖关系管理

    单体 Spring Boot Maven 工程 最基本的 pom.xml 包含工程信息.Spring Boot 父工程.属性配置.依赖包.构建插件 <?xml version="1.0 ...

  4. spring 最全MAVEN 依赖引入配置

    <properties> <spring.version>4.1.6.RELEASE</spring.version> </properties> &l ...

  5. Spring框架学习之高级依赖关系配置(二)

    紧接着上篇内容,本篇文章将主要介绍XML Schema的简化配置和使用SpEL表达式语言来优化我们的配置文件. 一.基于XML Schema的简化配置方式 从Spring2.0以来,Spring支持使 ...

  6. spring-第九篇之高级依赖关系配置

    1.关于配置文件一些使用 组件与组件之间的耦合,采用依赖注入管理:基本类型的成员变量值,应该直接在代码中设置. 2.获取其他bean的属性值 PorpertyPathFactoryBean用来获取目标 ...

  7. Jenkins job之间依赖关系配置(联动构建)

    使用场景: 想要在某APP打新包之后,立即执行自动化测试的job来验证该新包.比如Job A 执行完执行Job B ,如下图所示,如何建立依赖呢? 主要有两种方法: 1.配置上游依赖: 2.配置下游依 ...

  8. Jenkins-job之间依赖关系配置

    使用场景: 想要在某APP打新包之后,立即执行自动化测试的job来验证该新包. 比如Job A 执行完执行Job B ,如下图所示,如何建立依赖呢? 1.配置上游依赖 构建触发器-配置如下信息: 选择 ...

  9. Spring IOC - 控制反转(依赖注入) - 配置初始化和销毁的方法

    在Spring中如果某个bean在初始化之后,或销毁之前要做一些额外操作可以为该bean配置初始化和销毁的我方法,在这些方法中完成需要的功能. 实验: 通过断点调试模式,测试初始化方法和销毁方法的执行 ...

随机推荐

  1. 模拟时钟(AnalogClock)和数字时钟(DigitalClock)

    Demo2\clock_demo\src\main\res\layout\activity_main.xml <LinearLayout xmlns:android="http://s ...

  2. Gbase配置

    喵了个咪的.到目前为止,自己已经用过SQL SERVER,My SQL,Oracle,SQLite,加上南大通用GBASE 五种数据库了.虽然每种都用的不深 注:GBASE提供了C的API,查看手册即 ...

  3. linux上创建ftp服务器下载文件///使用AWS服务器作为代理,下载sbt相关的包

    最近觉得自己下载有些jar的速度太慢了,就在aws上下好了,然后转到我电脑上来,在aws上开了ftp服务器.结果就倒腾了一上午,作个记录,以便后面查看. 1.安装vsftpd yum -y insta ...

  4. Swift语言的基础详解

    1.1.关于swift · Swift 是一种适用于 iOS 和 OS X 应用的全新编程语言,它建立在最好的 C 和 Objective-C 语言之上,并且没有 C 语言的兼容性限制.Swift 采 ...

  5. 年底了,特贡献一些C#有意思的算法题

    2013年,即将要过去了.屌丝C#程序员们拿到了年终奖不?是不是又想蠢蠢欲动了?是不是想通过跳槽来为自己实现加薪的梦想?好吧,跳槽之前还是做点准备吧,准备好C#的笔试吧.这里我收集了些奉献给大家,大家 ...

  6. 为什么要放弃使用Thread.Sleep

    前言 此文并不是说要完全放弃使用Thread.Sleep,而是要说明在符合哪些情况下使用! 场景 很多时候,我们会需要一个定时服务来处理业务. 但并不是死死的每隔N分钟执行一次那种,而是在一次处理完后 ...

  7. 旺信UWP公测邀请

    各位园主好,今天已将旺信Win10版提交到商店Beta测试. 哪位朋友需要邀请码的,请在评论中回复,我给你私信. 数量有限,共10枚. 2016/3/10 14:55 更新 10枚邀请码已发给前10位 ...

  8. 作业二:Github注册账户过程

    Github注册账户过程如下: Github的注册及使用说明: [1]http://www.aehyok.com/Blog/Detail/73.html [2] http://www.cnblogs. ...

  9. [.NET自我学习]Delegate 泛型

    阅读导航 委托Delegate 泛型 1. 委托Delegate 继承自MulticastDelegate 声明委托定义签名: public delegate int DemoDelegate(int ...

  10. Git学习笔记(1)——安装,配置,创建库,文件添加到库

    初次接触git,为了记忆深刻,把学习的简单流程记录下来. 本文记录了Git在Ubuntu上的安装,配置,以及创建版本库和往库中添加文件的过程. 1.Git的安装:(Ubuntu-Linux非常友好的安 ...