spring 依赖注入(IOC DI)
依赖注入(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.4 Spring 依赖注入(DI)和控制反转(IOC)详解
自己开发了一个股票智能分析软件,功能很强大,需要的点击下面的链接获取: https://www.cnblogs.com/bclshuai/p/11380657.html 1.1 Spring 依赖注 ...
- Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)
一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...
- Spring依赖注入(DI)详解
一.依赖简介 一个典型的企业应用程序不是由一个单一的对象组成(或Spring的说法中的bean).即使是最简单的应用程序也只有几个对象一起工作来呈现最终用户看作是一个连贯的应用程序.如何从定义许多独立 ...
- Spring——依赖注入(DI)详解
声明:本博客仅仅是一个初学者的学习记录.心得总结,其中肯定有许多错误,不具有参考价值,欢迎大佬指正,谢谢!想和我交流.一起学习.一起进步的朋友可以加我微信Liu__66666666 这是简单学习一遍之 ...
- Spring依赖注入(IOC)那些事
小菜使用Spring有几个月了,但是对于它的内部原理,却是一头雾水,这次借着工作中遇到的一个小问题,来总结一下Spring. Spring依赖注入的思想,就是把对象交由Spring容器管理,使用者只需 ...
- 关于依赖注入IOC/DI的感想
之前一直不明白依赖注入有什么好处,甚至觉得它是鸡肋,现在想想,当时真是可笑. 这个想法正如同说接口是没有用处一样. 当整个项目非常庞大,各个方法之间的调用非常复杂,那么,可以想象一下,假设说没有任何的 ...
- Spring重温(三)--Spring依赖注入(DI)
前言:在Spring框架中,DI(依赖注入)是用来定义对象彼此间的依赖,主要有set方法注入和构造器注入两种方式.另外,当一个类包含多个构造函数带的参数相同,它总是会造成构造函数注入参数类型歧义的问题 ...
- 【10分钟学Spring】:(二)一文搞懂spring依赖注入(DI)
Spring最基础的特性就是创建bean.管理bean之间的依赖关系.下面通过具体实例演示该如何装配我们应用中的bean. Spring提供了三种主要的装配机制 在xml中进行显示的配置 在Java中 ...
- Spring 依赖注入(DI)简介
依赖注入的英文表示为dependency injection,缩写为DI. Spring框架的核心功能之一就是通过依赖注入的方式来管理Bean之间的依赖关系. 当编写一个复杂的 Java 应用程序时, ...
- Spring 依赖注入(DI)的注解
Spring中想要使用注解进行依赖注入,需要进行如下配置: <beans xmlns="http://www.springframework.org/schema/beans" ...
随机推荐
- Firemonkey 使用 TImage 显示动画图片
参考官网:http://docwiki.embarcadero.com/Libraries/Seattle/en/FMX.Ani.TBitmapListAnimation 延伸阅读:[工具] GIF ...
- jquery中ajax 从前端到后端 完整过程解析
几个原则: 1.get方式访问浏览器时,常加参数缘由: GET访问浏览器是等幂的,就是一个相同的URL只有一个结果[相同是指整个URL字符串完全匹配],所以第二次访问的时候如果 URL字符串没变化,浏 ...
- SDRAM,DRAM,SRAM,DDR的概念
一:SDRAM SDRAM(Synchronous Dynamic Random Access Memory),同步动态随机存储器,同步是指 Memory工作需要同步时钟,内部的命令的发送与数据的传输 ...
- python 学习笔记9(面向对象)
面向过程.函数式.面向对象 面向过程:根据业务逻辑从上到下写垒代码 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可 面向对象(Object Oriented Programmin ...
- ahjesus 前端缓存原理 转载
LAMP缓存图 从图中我们可以看到网站缓存主要分为五部分 服务器缓存:主要是基于web反向代理的静态服务器nginx和squid,还有apache2的mod_proxy和mod_cache模 浏览器缓 ...
- nodejs中全局变量
1.global 类似于客户端javascript运行环境中的window module1.js: module.exports={}; //耻辱的使用了全局变量 global.varA = &quo ...
- Struts2框架的自定义类型转换器
前言:对于java的基本数据类型及一些系统类(如Date类.集合类),Struts2提供了内置类型转换功能,但是也有一定的限制.所以就演示出自定义类型转换器 一.应用于局部类型转换器 eg.用户登录出 ...
- spring 整合 struts
struts配置 objectFactory 在struts.xml添加,用spring工厂管理action对象 <constant name="struts.objectFactor ...
- jQuery jquery.windy 快速浏览内容
在线实例 效果一 效果二 效果三 使用方法 <div class="container"> <section class="main" ...
- 10个漂亮的响应式的食品 WordPress 美食模板
您是否拥有一个餐厅,酒吧,咖啡馆,小酒馆,比萨饼店?如果答案是肯定的,请确保您在网上也提供服务.为了使您的工作更轻松,我们选择了一些新的和独特的餐厅主题,覆盖了范围很广的食品企业.这些主题提供了很多很 ...