Spring的依赖注入
依赖注入:Dependency Injection
控制反转:Inversion of Control
一、设值注入
public interface Person
...{
public void useAxe();
}
public interface Axe
...{
public void chop();
}
Person的实现类代码如下:
public class Chinese implements Person
...{
//面向Axe接口编程,而不是具体的实现类
private Axe axe;
//默认的构造器
public Chinese() ...{}
//设值注入所需的setter方法
public void setAxe(Axe axe) ...{
this.axe = axe;
}
//实现Person接口的useAxe方法
public void useAxe() ...{
System.out.println(axe.chop());
}
}
Axe的第一个实现类代码如下:
public class StoneAxe implements Axe
...{
public StoneAxe() ...{}
//实现Axe接口的chop方法
public String chop() ...{
return "石斧砍柴好慢";
}
}
下面采用Spring的配置文件将Person实例和Axe实例组织在一起。
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="chinese" class="prolove.Chinese">
<!--property元素用来指定需要容器注入的属性,axe属性需要容器
注入。此处是设值注入,因此Chinese类必须拥有setAxe方法-->
<property name="axe">
<!--此处将另一个bean的引用注入给chinese bean-->
<ref local="stoneAxe"/>
</property>
</bean>
<bean id="stoneAxe" class="prolove.StoneAxe"/>
</beans>
下面是主程序部分:
public class BeanTest
...{
public static void main(String[] args) throws Exception...{
//因为是独立的应用程序,显式实例化Spring的上下文
ApplicationContext ctx =
new FileSystemXmlApplicationContext("bean.xml");
//通过Person bean的id来获取bean实例,面向接口编程,因此
//此处强制类型转换为接口类型
Person p = (Person)ctx.getBean("chinese");
//直接执行Person的useAxe()方法
p.useAxe();
}
}
下面也给出了使用Ant编译和运行该应用的简单脚本:
<?xml version="1.0"?>
<project name="spring" basedir="." default="">
<path id="classpath">
<fileset dir="....lib">
<include name="*.jar"/>
</fileset>
<pathelement path="."/>
</path>
<target name="compile" description="Compile all source code">
<javac destdir="." debug="true"
deprecation="false" optimize="false" failonerror="true">
<src path="."/>
<classpath refid="classpath"/>
</javac>
</target>
<target name="run" description="run the main class" depends="compile">
<java classname="prolove.BeanTest" fork="yes" failonerror="true">
<classpath refid="classpath"/>
</java>
</target>
</project>
Axe的另一个实现类如下:
public class SteelAxe implements Axe
...{
public SteelAxe() ...{}
public String chop() ...{
return "钢斧砍柴真快";
}
}
Spring配置:
<bean id="steelAxe" class="prolove.SteelAxe"/>
<ref local="steelAxe"/>
二、构造注入
public class Chinese implements Person
...{
//面向Axe接口编程,而不是具体的实现类
private Axe axe;
//默认的构造器
public Chinese() ...{}
//构造注入所需的带参数的构造器
public Chinese(Axe axe) ...{
this.axe = axe;
}
//实现Person接口的useAxe方法
public void useAxe() ...{
System.out.println(axe.chop());
}
}
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="chinese" class="prolove.Chinese">
<constructor-arg><ref bean="stoneAxe"/></constructor-arg>
</bean>
<bean id="stoneAxe" class="prolove.StoneAxe"/>
</beans>
三、两种注入方式的对比
建议采用以设值注入为主,构造注入为辅的注入策略。对于依赖关系无须
变化的注入,尽量采用构造注入;而其他的依赖关系的注入,则考虑采用设值注入。
推荐文章 |
