依赖注入(IOC DI)

依赖注入的两种方式:

1. set注入

Spring要求使用set注入方式的时候,Bean需要提供一个无参数的构造方法。并提供一个属性的setter方法。例如:

package com.kay.bean;

public class UserServices {

private UserBean ub;

public void setUb(UserBean ub) {

this.ub = ub;

}

public void add(){

ub.add();

}

}

在上面的例子中UserServices类依赖与UserBean类,那么可以在配置文件中进行配置。

配置方法1:

<!-- 将userBean交给spring管理 -->

<bean id="userBean" class="com.kay.bean.UserBean"/>

<!-- 将userServics交给spring管理 -->

<bean id="userServices" class="com.kay.bean.UserServices">

<!-- 利用propterty节点进行setter方法的注入 -->

<property name="ub"><ref bean="userBean"/></property>

</bean>

在配置文件中preperty节点中的name属性指的是UserServices类中的set方法的名字,比如setXXX,和属性名字无关。ref节点的bean属性指的是要引用的一个Bean,并将引用的Bean的实例注入到UserServices类中。

配置方法2:

<bean id="userBean" class="com.kay.bean.UserBean"/>

<bean id="userServices" class="com.kay.bean.UserServices">

<property name="ub"><ref local="userBean"/></property>

</bean>

上面的配置文件将原来的ref节点中的bean属性改为了local,那么local属性要求引用的Bean必须在同一配置文件中(Spring支持多配置文件)。但是bean属性则没有这个要求。

配置方法3:

<bean id="userServices" class="com.kay.bean.UserServices">

<property name="ub">

<bean class="com.kay.bean.UserBean"/>

</property>

</bean>

上面的这种配置方式成为内部Bean配置。内部Bean的定义不需要有id或name的指定,如果你指定也会被Spring容器忽略。这样配置的缺陷是引用的Bean无法得到重用,并且内部Bean是prototype的。

配置方法4:

<bean id="userBean" class="com.kay.bean.UserBean"/>

<bean id="userServices" class="com.kay.bean.UserServices">

<property name="ub" ref="userBean"/>

</bean>

这种写法只是配置方法1的简写形式。

2. 构造方法注入

从注入方面的名称上就可以看出,这种注入方式主要利用的是构造方法。把UserServices类修改为:

package com.kay.bean;

public class UserServices {

private UserBean userBean;

public UserServices(UserBean userBean){

this.userBean = userBean;

}

public void add(){

userBean.add();

}

}

配置方法1:

<bean id="userBean" class="com.kay.bean.UserBean"/>

<bean id="userServices" class="com.kay.bean.UserServices">

<constructor-arg>

<ref bean="userBean"/>

</constructor-arg>

</bean>

上面使用了constructor-arg节点,该节点的ref子结点bean属性指定了要引用的Bean。

如果在UserServices类中有这样的构造方法:

package com.kay.bean;

public class UserServices {

private String name;

public int a;

public UserServices(String name,int a){

this.name = name;

this.a = a;

}

}

那么可以使用配置方法2和配置方法3来解决。

配置方法2:

<bean id="userServices" class="com.kay.bean.UserServices">

<constructor-arg type="java.lang.String" value="Tom"/>

<constructor-arg type="int" value="25"/>

</bean>

在配置方法2中使用type属性指定了构造方法参数的类型,value指定参数的值。

配置方法3:

<bean id="userServices" class="com.kay.bean.UserServices">

<constructor-arg index="0" value="Tom"/>

<constructor-arg index="1" value="25"/>

</bean>

在配置方法3中使用index属性指定构造方法中的参数的顺序。

使用构造方法注入还是set注入?

首先告诉你该问题没有答案!!!

使用构造方法注入的理由:

n 构造方法注入使用强依赖规定,如果不给足够的参数,对象则无法创建。

n 由于Bean的依赖都通过构造方法设置了,那么就不用写更多的set方法,有助于减少代码量。

使用set注入的理由:

n 如果Bean有很多的依赖,那么构造方法的参数列表会变的很长。

n 如果一个对象有多种构造方法,构造方法会造成代码量增加。

n 如果构造方法中有两个以上的参数类型相同,那么将很难确定参数的用途。

n ……

Spring官方更推荐使用set注入。

更多注入:

从User类来开始:

public class User {

private int age;

private String name;

private double score;

private List fav;

private Map map;

private Set set;

private Properties pro;

public void setAge(int age) {

this.age = age;

}

public void setName(String name) {

this.name = name;

}

public void setScore(double score) {

this.score = score;

}

public void setFav(List fav) {

this.fav = fav;

}

public void setMap(Map map) {

this.map = map;

}

public void setSet(Set set) {

this.set = set;

}

public void setPro(Properties pro) {

this.pro = pro;

}

}

1. 注入直接变量(基本数据类型,String类型等)

<bean id="user" class="com.kay.bean.User">

<property name="age" value="45"></property>

<property name="name" value="Tom"></property>

<property name="score" value="45.5"></property>

</bean>

或:

<bean id="user" class="com.kay.bean.User">

<property name="age">

<value>45</value>

</property>

<property name="name">

<value>Tom</value>

</property>

<property name="score">

<value>45.5</value>

</property>

</bean>

当然构造方法注入的方式也是可以的:

<bean id="user" class="com.kay.bean.User">

<constructor-arg type="int" value="45"></constructor-arg>

<constructor-arg type="double" value="45.5"></constructor-arg>

<constructor-arg type="java.lang.String" value="Tom"></constructor-arg>

</bean>

2. 集合

a) List

<property name="fav">

<list>

<value>football</value>

<value>pingpang</value>

<value>swing</value>

</list>

</property>

b) Set

<property name="set">

<set>

<value>set1</value>

<value>set2</value>

<value>set3</value>

</set>

</property>

c) Map

<property name="map">

<map>

<entry>

<key>

<value>id</value>

</key>

<value>001</value>

</entry>

<entry>

<key>

<value>name</value>

</key>

<value>jerry</value>

</entry>

</map>

</property>

d) Properties

<property name="pro">

<props>

<prop key="name">Tom</prop>

<prop key="age">15</prop>

</props>

</property>

3. Null

配置节点<null/>用于处理null值。

<property name="name">

<null></null>

</property>

上述配置相当于setName(null);

如果这样配置:

<property name="name">

<value></value>

</property>

则相当于setName(“”);

4. 使用p命名空间进行属性注入

修改配置文件的schema:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.5.xsd

http://www.springframework.org/schema/context

http://www.springframework.org/schema/context/spring-context-2.5.xsd">

</beans>

注入属性:

<bean id="user" class="com.kay.bean.User" p:name="tom" p:age="45" p:score="55.5">

</bean>

在上面的设置中使用了命名空间p,p:name则代表给name属性进行赋值,如果User类中有一个属性需要引用其他的Bean,则需要这样配置p:属性名-ref=”要引用的Bean”:

<bean id="userBean" class="com.kay.bean.UserBean"/>

<bean id="user" class="com.kay.bean.User" p:name="tom" p:age="45" p:score="55.5" p:userbean-ref="userBean">

</bean>

5. Bean的自动装配(注入)

Spring提供了以下四种自动装配类型:

n byName à试图在容器中寻找和需要自动装配的属性名相同的Bean(或ID)。如果没有找到,这个属性就没有被转配上。

n byType à 试图在容器中寻找一个与需要自动装配的属性类型相同的Bean。如果没有找到相符的Bean,这个属性就没有被装配,如果找到超过一个相符的Bean,会抛出org.springframework.bean.factory.UnsatisfiedDependencyException异常。

n Constructor à试图在容器中查找与需要自动装配的Bean的构造函数一致的一个或多个Bean。古国存在不确定的Bean或构造函数,容器抛出org.spingframework.beans.factory. UnsatisfiedDependencyException异常。

n Autodetect à首先尝试使用constrctor来装配,然后采用byType方式。不确定性的处理与constrctor和byType方式一样。

使用byName进行自动装配:

UserDAO类:

public class UserDAO {

public void add(){

System.out.println("使用JDBC进行添加操作");

}

}

UserServices类:

public class UserServices {

private UserDAO userDAO;

public void setUserDAO(UserDAO userDAO) {

this.userDAO = userDAO;

}

public void add(){

userDAO.add();

}

}

使用byName自动装配:

<bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

<bean id="userService" class="com.kay.bean.UserServices" autowire="byName">

</bean>

在使用byName自动装配的时候,需要将Bean中注入的属性名设置为和要注入的Bean名称一样。(黄色部分)

使用byType进行自动装配:

在使用byType进行自动装配的时候,和使用byName进行装配工作方式的相同的,只不过是通过属性的类型进行寻找相关Bean进行装配的。

<bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

<bean id="userService" class="com.kay.bean.UserServices" autowire="byType">

</bean>

在使用buType自动装配的时候,如果Spring找到和需要注入的Bean的类型相同的Bean个数超过了一个,Spring不会决定将哪个Bean注入,而是直接抛出异常。

使用constructor进行自动装配:

修改UserService类:

public class UserServices {

private UserDAO userDAO;

public UserServices( UserDAO userDAO)

{

this.userDAO = userDAO;

}

public void add(){

userDAO.add();

}

}

修改配置文件:

<bean id="userDAO" class="com.kay.bean.UserDAO"></bean>

<bean id="userService" class="com.kay.bean.UserServices" autowire="constructor">

</bean>

在使用constructor进行自动转配的时候,Spring容器会寻找匹配Bean的构造方法的Bean进行注入,和ByType一样,如果容器找到一个以上的匹配Bean,同样不会决定将哪个Bean进行注入,而是抛出异常。

使用autodetect自动装配:

<bean id="userService" class="com.kay.bean.UserServices" autowire="autodetect">

</bean>

将atuowire属性值设置为autodetect,那么将由Spring容器决定使用哪种装配方式。容器会先尝试使用constructor进行装配,如果失败则会使用byTyep进行装配。

在默认的情况下,Spring容器不会进行自动装配,除非在配置文件中设置了autowire属性,如果设置beans节点的default-autowire属性,那么所有的Bean都会采用自动装配。

<beans default-autowire="byName">

</beans>

采用上述设置后,所有的Bean都采用byName方式进行装配。

spring 依赖注入(IOC DI)的更多相关文章

  1. 1.4 Spring 依赖注入(DI)和控制反转(IOC)详解

    自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1  Spring 依赖注 ...

  2. Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)

    一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...

  3. Spring依赖注入(DI)详解

    一.依赖简介 一个典型的企业应用程序不是由一个单一的对象组成(或Spring的说法中的bean).即使是最简单的应用程序也只有几个对象一起工作来呈现最终用户看作是一个连贯的应用程序.如何从定义许多独立 ...

  4. Spring——依赖注入(DI)详解

    声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...

  5. Spring依赖注入(IOC)那些事

    小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...

  6. 关于依赖注入IOC/DI的感想

    之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...

  7. Spring重温(三)--Spring依赖注入(DI)

    前言:在Spring框架中,DI(依赖注入)是用来定义对象彼此间的依赖,主要有set方法注入和构造器注入两种方式.另外,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题 ...

  8. 【10分钟学Spring】:(二)一文搞懂spring依赖注入(DI)

    Spring最基础的特性就是创建bean.管理bean之间的依赖关系.下面通过具体实例演示该如何装配我们应用中的bean. Spring提供了三种主要的装配机制 在xml中进行显示的配置 在Java中 ...

  9. Spring 依赖注入(DI)简介

    依赖注入的英文表示为dependency injection,缩写为DI. Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系. 当编写一个复杂的 Java 应用程序时, ...

  10. Spring 依赖注入(DI)的注解

    Spring中想要使用注解进行依赖注入,需要进行如下配置: <beans xmlns="http://www.springframework.org/schema/beans" ...

随机推荐

  1. C4.5,CART,randomforest的实践

    #################################Weka-J48(C4.5)################################# ################### ...

  2. 第四篇 SQL Server安全权限

    本篇文章是SQL Server安全系列的第四篇,详细内容请参考原文. 权限授予主体访问对象,以执行某些操作.SQL Server有大量你可以授予给主体的权限,你甚至可以拒绝或回收权限.这听起来有点复杂 ...

  3. 关于HTML5应用开发功耗调优化小结

    HTML5的优化一直是困扰我的难题,特别是在移动端开发游戏和应用,所以对此进行了一些总结: 功耗优化点介绍 在移动设备中主要的功耗点在: 1. 网络的传输, 不管是3G网络还是WiFi传输都是移动设备 ...

  4. pos机套现是怎么回事

    POS机是商家为了促进消费,向银行申请的刷卡机它的主要功能是转账就是通过客户的刷卡,把相对的金额转入商户的帐户银行会根据笔数或金额向商户收取手续费非法套现就是客户并未和商户产生贸易往来,单纯通过pos ...

  5. Java Web编程的主要组件技术——Struts的高级功能

    参考书籍:<J2EE开源编程精要15讲> Struts对国际化的支持 "国际化"(I18N)指一个应用程序在运行时能根据客户端请求所来的国家/地区.语言的不同显示不同的 ...

  6. 搭建mongodb分片

    搭建mongodb分片 http://gong1208.iteye.com/blog/1622078 Sharding分片概念 这是一种将海量的数据水平扩展的数据库集群系统,数据分表存储在shardi ...

  7. 使用URLConnection调用axis1.4开发的webservice

    写在前面: 调用webservice的方式有很多:1.直接在客户端使用工具生成客户端代码,将代码拷进项目中调用即可:2.使用对应的webservice框架来进行调用,比如如果我们我的服务端开发用的是a ...

  8. Spring初学

    一.spring体系结构spring核心组件 1.Beans(包装应用程序自定义对象Object,Object中存有数据) 2.Core (资源加载,资源抽象,建立维护与bean之间的一些关系所需的一 ...

  9. ADB 安卓开发配置环境

    下载完后将名称中含有adb的文件,和fastboot.exe复制到 c:/windows/system32目录 或c:/windows/system64目录(看自己电脑系统配置 如电脑64操作系统就写 ...

  10. English trip EM2-MP4 Teacher:Taylor voiceless consonant 清辅音 &amp; voiced consonant 浊辅音

    课上内容(Lesson) # 区分 voiceless consonant 清辅音 & voiced consonant 浊辅音 清辅音    short   # 轻快 浊辅音    long ...