文档章节

Spring Dependencies Injection

zswitos
 zswitos
发布于 2015/04/29 18:12
字数 1388
阅读 122
收藏 4

Spring Dependencies Injection

1、construtor argsInjection

    1.1 ref注入

<beans>
    <bean id="foo" class="x.y.Foo">
        <constructor-arg ref="bar"/>
        <constructor-arg ref="baz"/>
    </bean>

    <bean id="bar" class="x.y.Bar"/>
    <bean id="baz" class="x.y.Baz"/>

</beans>

package x.y;
public class Foo {
    public Foo(Bar bar, Baz baz) {
    // ...
    }
}

此时会根据类型匹配相应的构造器参数,进行注入

    1.2 指定type类型 注入


public class ExampleBean {
    // Number of years to calculate the Ultimate Answer
    private int years;
    // The Answer to Life, the Universe, and Everything
    private String ultimateAnswer;
    public ExampleBean(int years, String ultimateAnswer) {
    this.years = years;
    this.ultimateAnswer = ultimateAnswer;
    }
}


<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg type="int" value="7500000"/>
    <constructor-arg type="java.lang.String" value="42"/>
</bean>


    1.3 指定index注入

<bean id="exampleBean" class="examples.ExampleBean">
    <constructor-arg index="0" value="7500000"/>
    <constructor-arg index="1" value="42"/>
</bean>


    1.4 使用注解注入

package examples;
public class ExampleBean {
    // Fields omitted
    @ConstructorProperties({"years", "ultimateAnswer"})
    public ExampleBean(int years, String ultimateAnswer) {
        this.years = years;
        this.ultimateAnswer = ultimateAnswer;
    }
}

2、Setter-based dependency injection

    是时候用构造器注入,啥时候用setter哪,一个经验说:必须的参数需要构造器注入,其他的可以用setter,但是,也可以用@Required annotation去显示指定必须的参数

    2.1 简单的set注入

        

public class SimpleMovieLister {
    // the SimpleMovieLister has a dependency on the MovieFinder
    private MovieFinder movieFinder;
    // a setter method so that the Spring container can inject a MovieFinder
    public void setMovieFinder(MovieFinder movieFinder) {
        this.movieFinder = movieFinder;
    }
    // business logic that actually uses the injected MovieFinder is omitted...
}

<bean id="simpleMovieLister" class = "...">
    <property name = "movieFinder" ref = "movieFinder"></property>
</bean>

    大量的setter注入需要灰常多的的非空判断,所以spring的官方推荐是用constructor的注入,如果需要传入的参数过多,建议使用工厂方法,哦耶!

3、依赖解析流程

    第一步:

            ApplicationContext创建,使用通过xml,java code ,annotation配置的元数据进行初始化beandefinition,

            (The ApplicationContext is created and initialized with configuration metadata that describes all
the beans. Configuration metadata can be specified via XML, Java code, or annotations.)

    第二步:

            获取到每个通过构造函数,setter,property,工厂方法注入的属性(ref,基本数据类型),在这个bena被创建的时候赋值给他

            (For each bean, its dependencies are expressed in the form of properties, constructor arguments, or
arguments to the static-factory method if you are using that instead of a normal constructor. These
dependencies are provided to the bean, when the bean is actually created.)

    第三步:

            

    每个属性或构造函数参数的定义的参数都是一个集合,或者基本数据类型,或者容器中另外一个bean的引用。

    (Each property or constructor argument is an actual definition of the value to set, or a reference to
another bean in the container)

    

    第四步:

    每个构造器参数或者属性都是被转化为实际的类型,默认的spring会转化value为任何一个基本类型int,long,boolean,String等

   ( Each property or constructor argument which is a value is converted from its specified format to the
actual type of that property or constructor argument. By default Spring can convert a value supplied
in string format to all built-in types, such as int, long, String, boolean, etc.)


循环依赖(Circular dependencies)注入

    加入你顶一个class A,他的构造器里面需要参数为Class B,同时,class B的构造器需要一个Class A这时候Spring注入会陷入循环当中,抛出一个BeanCurrentlyInCreationException的异常

咋办,虽然推荐用构造器注入好,但是这种情况下,你要变通下,用setter注入不就好了吗,ok!

这是一个经典的哲学问题,先有鸡还是先有蛋(a classic chicken/egg scenario)

虽Spring会有问题,但是通常情况下你要相信Spring的解决能力,当在load的时候他不会影响整个系统的因为单个bean的注入问题,只有在整个bean被创建的时候才会报错,值得学习的思想



属性 idref

    idef可以在容器初始化之前经行验证,制定的id的ref对象是否存在

<bean id="theTargetBean" class="..."/>
<bean id="theClientBean" class="...">
<property name="targetName">
<idref bean="theTargetBean" />
</property>
</bean>


属性ref

<bean id="theTargetBean" class="..."/>
<bean id="theClientBean" class="...">
<property name="targetName">
<ref id="theTargetBean" />
</property>
</bean>

引用父级的元素
<!-- in the parent context -->
<bean id="accountService" class="com.foo.SimpleAccountService">
<!-- insert dependencies as required as here -->
</bean>
<!-- in the child (descendant) context -->
<bean id="accountService" <!-- bean name is the same as the parent bean -->
class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target">
<ref parent="accountService"/> <!-- notice how we refer to the parent bean -->
</property>
<!-- insert other configuration and dependencies as required here -->
</bean>


内部类


    这个内部类显示去配置声明一个bean元素时候不需要指定id 或者name,容器不会去需要这个,而且scope也不需要

<bean id="outer" class="...">
<!-- instead of using a reference to a target bean, simply define the target bean inline -->
<property name="target">
<bean class="com.example.Person"> <!-- this is the inner bean -->
<property name="name" value="Fiona Apple"/>
<property name="age" value="25"/>
</bean>
</property>
</bean>



集合Collections

      

  <bean id="moreComplexObject" class="example.ComplexObject">
<!-- results in a setAdminEmails(java.util.Properties) call -->
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.org</prop>
<prop key="support">support@example.org</prop>
<prop key="development">development@example.org</prop>
</props>
</property>
<!-- results in a setSomeList(java.util.List) call -->
<property name="someList">
<list>
<value>a list element followed by a reference</value>
<ref bean="myDataSource" />
</list>
</property>
<!-- results in a setSomeMap(java.util.Map) call -->
<property name="someMap">
<map>
<entry key="an entry" value="just some string"/>
<entry key ="a ref" value-ref="myDataSource"/>
</map>
</property>
<!-- results in a setSomeSet(java.util.Set) call -->
<property name="someSet">
<set>
<value>just some string</value>
<ref bean="myDataSource" />
</set>
</property>
</bean>


自动合并父级集合属性,merge
<beans>
<bean id="parent" abstract="true" class="example.ComplexObject">
<property name="adminEmails">
<props>
<prop key="administrator">administrator@example.com</prop>
<prop key="support">support@example.com</prop>
</props>
</property>
</bean>
<bean id="child" parent="parent">
<property name="adminEmails">
<!-- the merge is specified on the child collection definition -->
<props merge="true">
<prop key="sales">sales@example.com</prop>
<prop key="support">support@example.co.uk</prop>
</props>
</property>
</bean>
<beans>



depends-on


ref有时候不太强大,当你需要初始化你的类之前,需要确保你的引用类一定被先初始化,这时候该标签有了一个强大力量

<bean id="beanOne" class="ExampleBean" depends-on="manager"/>
<bean id="manager" class="ManagerBean" />

The depends-on attribute in the bean definition can specify both an initialization time dependency
and, in the case of singleton beans only, a corresponding destroy time dependency. Dependent
beans that define a depends-on relationship with a given bean are destroyed first, prior to the
given bean itself being destroyed. Thus depends-on can also control shutdown order.





© 著作权归作者所有

共有 人打赏支持
zswitos
粉丝 4
博文 60
码字总数 55712
作品 0
海淀
程序员
私信 提问
浅谈application-*.xml和springmvc-.xml的区别

项目配置说明 一般springMVC和Spring的整合过程中,我们喜欢配置两个文件application-*.xml和springmvc-.xml,但是配置不好的话,很容易出现这样的问题:Injection of resource dependencie...

小车车
2016/07/07
10
0
springMVC+spring3.2.3+mybatis3启动tomcat报异常???

Error creating bean with name 'personBizImpl': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not......

so_co
2014/03/05
744
3
Spring Bean注入失败

错误信息: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'businessCommon': Injection of autowired dependencies failed; nested exception ......

酸奶瓶盖儿
05/17
0
0
Creating a REST API with Spring Boot and MongoDB

Spring Boot is an opinionated framework that simplifies the development of Spring applications. It frees us from the slavery of complex configuration files and helps us to creat......

perfectspr
2014/12/11
0
0

没有更多内容

加载失败,请刷新页面

加载更多

防止Tweak

什么是tweak? 英文意思为捏, 拧,扭,稍稍调整(机器、系统等)。 依据维基百科的定义,tweak指的是对电子系统进行轻微调整来增强其功能的工具;在ios中tweak特指那些能够增强其它可执行程...

HeroHY
9分钟前
0
0
linux中常用标识---不定期更新

LINUX常用标识符: 1 & && | || &: 表示进程在后台运行 例如 redis-server & 不是所有后台运行都是& 比如es ./bin/elasticsearch -d es后台运行&&: 第一个命令执行成功后 才执行后面的命令...

geek土拨鼠
47分钟前
1
0
Mybatis 中$与#的区别,预防SQL注入

一直没注意Mybatis 中$与#的区别,当然也是更习惯使用#,没想到避免了SQL注入,但是由于要处理项目中安全渗透的问题,不可避免的又遇到了这个问题,特此记录一下。 首先是共同点: 在mybatis...

大雁南飞了
今天
0
0
Spring Clould负载均衡重要组件:Ribbon中重要类的用法

Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡,而不必在项目里过多地编写实现...

Ala6
今天
0
0
让 linux 删除能够进入回收站

可以参考这个贴子 https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79543316 从那个git地址 把saferm.sh下载下来 把saferm.sh复制到 /usr/bin 目录下 在用~/目下 的.bashrc 下加一句这...

shzwork
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部