Spring(二) 依赖注入
2016-07-27 12:38
387 查看
1. Spring的核心机制:[b]依赖注入(Dependency Injection)[/b]
Spring框架的核心功能有2个:
(1) Spring容器作为超级大工厂,负责创建、管理所有java对象,这些java对象被称为Bean。
(2) Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为“依赖注入”的方式来管理Bean之间的依赖关系。
依赖注入是种优秀的解耦方式。让Spring的Bean以配置文件组织在一起,而不是硬编码方式耦合在一起。
1.1 理解依赖注入:
依赖注入(Dependency Injection)和控制反转(Inversion of Control, IoC)是一个意思。
使用Spring框架之后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受(Sping框架提供)————于是Rod Johnson将这种方式称为控制反转。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量————相当于为调用者注入它依赖的实例。所以Martine Fowler将这种方式称为依赖注入。
依赖注入有2种方式:
(1)设值注入:IoC容器使用成员变量的setter方法来注入被依赖的对象。
(2)构造注入:IoC容器使用构造器来注入被依赖的对象。
1.2 设值注入:
Spring推荐面向接口编程。不管是调用者,还是被依赖对象,都应该为之定义接口,程序应该面向它们的接口,而不是面向实现类编程,这样方便后续升级、维护。
创建2个组件的接口:
Axe.java:
分别定义Axe和Person的实现类:
Chinese.java
beans02.xml(配置文件):
Spring IoC容器的3个基本要点:
(1)应用程序要面向接口编程。面向接口编程可以将组件之间的耦合关系提升到接口层次,从而有利于项目后期的扩展。
(2)应用程序的各个组件不再由程序主动创建,而是由Spring容器来负责产生并初始化。
(3)Spring采用配置文件或者注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。
1.3 构造注入:
利用构造器来设置依赖关系的方式,被称为构造注入。驱动Spring在底层以反射方式执行带指定参数的构造器。在bean配置文件中,每个<constructor-arg.../>子元素代表一个构造器参数,如果<bean.../>元素包含N个<constructor-arg.../>子元素,就会驱动Spring调用带N个参数的构造器来创建对象。
<constructor-arg.../>可以指定一个name属性,name指代构造器参数名。
<constructor-arg.../>可以指定一个Index属性,用于指定该构造参数值将作为第几个构造参数值,index = "0"代表第一个构造参数值。
<constructor-arg.../>可以指定一个type属性,用于确定该属性值的数据类型。例如<constructor-arg value="23" type="int">
新建一个Person接口的实例,
Canadian.java
BeanTest.java
1.4 总结:
设值注入是先通过无参数的构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则直接调用有参数的构造器,当Bean实例创建完成后,已经完成了依赖关系的注入。
两种注入方式有其各自的优势。应该以设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其他依赖关系的注入,则考虑采用设值注入。
Spring框架的核心功能有2个:
(1) Spring容器作为超级大工厂,负责创建、管理所有java对象,这些java对象被称为Bean。
(2) Spring容器管理容器中Bean之间的依赖关系,Spring使用一种被称为“依赖注入”的方式来管理Bean之间的依赖关系。
依赖注入是种优秀的解耦方式。让Spring的Bean以配置文件组织在一起,而不是硬编码方式耦合在一起。
1.1 理解依赖注入:
依赖注入(Dependency Injection)和控制反转(Inversion of Control, IoC)是一个意思。
使用Spring框架之后,调用者获取被依赖对象的方式由原来的主动获取,变成了被动接受(Sping框架提供)————于是Rod Johnson将这种方式称为控制反转。
从Spring容器的角度来看,Spring容器负责将被依赖对象赋值给调用者的成员变量————相当于为调用者注入它依赖的实例。所以Martine Fowler将这种方式称为依赖注入。
依赖注入有2种方式:
(1)设值注入:IoC容器使用成员变量的setter方法来注入被依赖的对象。
(2)构造注入:IoC容器使用构造器来注入被依赖的对象。
1.2 设值注入:
Spring推荐面向接口编程。不管是调用者,还是被依赖对象,都应该为之定义接口,程序应该面向它们的接口,而不是面向实现类编程,这样方便后续升级、维护。
创建2个组件的接口:
Axe.java:
package com.pmpa.ch02; public interface Axe { public String chop(); }Person.java:
package com.pmpa.ch02; public interface Person { public void useAxe(); }
分别定义Axe和Person的实现类:
Chinese.java
package com.pmpa.ch02; public class Chinese implements Person { private Axe axe; public void setAxe(Axe axe) { this.axe = axe; } @Override public void useAxe() { // TODO Auto-generated method stub System.out.println("Chinese " + axe.chop()); } }StoneAxe.java
package com.pmpa.ch02; public class StoneAxe implements Axe { @Override public String chop() { return "石斧子砍柴慢!!"; } }Japanese.java
package com.pmpa.ch02; public class Japanese implements Person { private Axe axe; public void setAxe(Axe axe) { this.axe = axe; } @Override public void useAxe() { // TODO Auto-generated method stub System.out.println("Japanese " + axe.chop()); } }SteelAxe.java
package com.pmpa.ch02; public class SteelAxe implements Axe { @Override public String chop() { // TODO Auto-generated method stub return "钢斧子砍柴快!!!"; } }程序没有为Person实例传入Axe实例,Axe实例由Spring在运行期间注入。
beans02.xml(配置文件):
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="stoneaxe" class="com.pmpa.ch02.StoneAxe"></bean> <bean id="chinese" class="com.pmpa.ch02.Chinese"> <property name = "axe" ref="stoneaxe"></property> </bean> <bean id="steelaxe" class="com.pmpa.ch02.SteelAxe"></bean> <bean id="japanese" class="com.pmpa.ch02.Japanese"> <property name = "axe" ref="steelaxe"></property> </bean> </beans>测试程序BeanTest.java
package com.pmpa.ch02; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class BeanTest { public static void main(String[] args) { // TODO Auto-generated method stub ApplicationContext ctx = new ClassPathXmlApplicationContext("conf/beans02.xml"); Chinese ci = ctx.getBean("chinese", Chinese.class); ci.useAxe(); Japanese jn = ctx.getBean("japanese", Japanese.class); jn.useAxe(); } }
Spring IoC容器的3个基本要点:
(1)应用程序要面向接口编程。面向接口编程可以将组件之间的耦合关系提升到接口层次,从而有利于项目后期的扩展。
(2)应用程序的各个组件不再由程序主动创建,而是由Spring容器来负责产生并初始化。
(3)Spring采用配置文件或者注解来管理Bean的实现类、依赖关系,Spring容器则根据配置文件或注解,利用反射来创建实例,并为之注入依赖关系。
1.3 构造注入:
利用构造器来设置依赖关系的方式,被称为构造注入。驱动Spring在底层以反射方式执行带指定参数的构造器。在bean配置文件中,每个<constructor-arg.../>子元素代表一个构造器参数,如果<bean.../>元素包含N个<constructor-arg.../>子元素,就会驱动Spring调用带N个参数的构造器来创建对象。
<constructor-arg.../>可以指定一个name属性,name指代构造器参数名。
<constructor-arg.../>可以指定一个Index属性,用于指定该构造参数值将作为第几个构造参数值,index = "0"代表第一个构造参数值。
<constructor-arg.../>可以指定一个type属性,用于确定该属性值的数据类型。例如<constructor-arg value="23" type="int">
新建一个Person接口的实例,
Canadian.java
package com.pmpa.ch02; public class Canadian implements Person { private int age; private Axe axe; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Axe getAxe() { return axe; } public void setAxe(Axe axe) { this.axe = axe; } //重点关注此处,构造方法,不能写成public void Canadian() public Canadian (int age, Axe axe) { this.age = age; this.axe = axe; } @Override public void useAxe() { // TODO Auto-generated method stub System.out.println("Canadian " + "aged " + age + " " + axe.chop() ); } }相应beans02.xml添加内容:
<bean id="canadian" class="com.pmpa.ch02.Canadian"> <constructor-arg name="age" value="30" index ="0" ></constructor-arg> <constructor-arg name="axe" ref="steelaxe" index="1"></constructor-arg> </bean>最终测试类添加:
BeanTest.java
Canadian ca = ctx.getBean("canadian", Canadian.class); ca.useAxe();最终结果:
Chinese 石斧子砍柴慢!! Japanese 钢斧子砍柴快!!! Canadian aged 30 钢斧子砍柴快!!
1.4 总结:
设值注入是先通过无参数的构造器创建一个Bean实例,然后调用对应的setter方法注入依赖关系;而构造注入则直接调用有参数的构造器,当Bean实例创建完成后,已经完成了依赖关系的注入。
两种注入方式有其各自的优势。应该以设值注入为主,构造注入为辅的注入策略。对于依赖关系无需变化的注入,尽量采用构造注入;而其他依赖关系的注入,则考虑采用设值注入。
相关文章推荐
- 一个jar包里的网站
- 一个jar包里的网站之文件上传
- 一个jar包里的网站之返回对媒体类型
- Spring和ThreadLocal
- Spring Boot 开发微服务
- Spring AOP动态代理-切面
- Spring整合Quartz(JobDetailBean方式)
- Spring整合Quartz(JobDetailBean方式)
- NopCommerce架构分析(一)Autofac依赖注入类生成容器
- JavaScript中的依赖注入详解
- 浅析依赖注入框架Autofac的使用
- 浅析Node.js中使用依赖注入的相关问题及解决方法
- 模拟Spring的简单实现
- Spring整合WebSocket应用示例(上)
- spring+html5实现安全传输随机数字密码键盘
- Spring中属性注入详解
- 监听器获取Spring配置文件的方法
- Java利用Sping框架编写RPC远程过程调用服务的教程
- springmvc 发送ajax出现中文乱码的解决方法汇总