文档章节

Spring Dependencies Injection

zswitos
 zswitos
发布于 2015/04/29 18:12
字数 1388
阅读 119
收藏 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
海淀
程序员
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
浅谈application-*.xml和springmvc-.xml的区别

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

小车车
2016/07/07
10
0
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

没有更多内容

加载失败,请刷新页面

加载更多

面向对象设计原则(OOP)

单一职责原则(Single responsibility principle)又称单一功能原则。它规定一个类应该只有一个发生变化的原因。 核心原则:低耦合,高内聚。 一个类,应该只有一个引起它变化的原因,也就是...

gackey
33分钟前
2
0
C++ 锁

C++提供了两种常用的锁,std::lock_guard<Lockable &T>和std::unique_lock<Lockable &T>。通常使用场景下,这两个锁用法一致。即,在构造锁对象时上锁,在析构锁对象时解锁。使用户从上锁/解...

yepanl
36分钟前
2
0
Kali Linux Docker 練習

docker pull kalilinux/kali-linux-docker docker run -t -i kalilinux/kali-linux-docker /bin/bash apt-get update apt-get install htop apt-get install nmap apt-get install wpscan ap......

BaiyuanLab
今天
2
0
通俗大白话来理解TCP协议的三次握手和四次分手

最近在恶补计算机网络方面的知识,之前对于TCP的三次握手和四次分手也是模模糊糊,对于其中的细节更是浑然不知,最近看了很多这方面的知识,也在系统的学习计算机网络,加深自己的CS功底,就...

onedotdot
今天
2
0
TiDB 在爱奇艺的应用及实践

爱奇艺,中国高品质视频娱乐服务提供者,2010 年 4 月 22 日正式上线,推崇品质、青春、时尚的品牌内涵如今已深入人心,网罗了全球广大的年轻用户群体,积极推动产品、技术、内容、营销等全方...

TiDB
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部