Spring之实现依赖注入DI(1.0)
依赖注入
在Spring中最为核心的两大组件:IOC&DI、AOP,其中IOC称为控制反转,实际上也就相当于将对象的创建权利交由Spring负责处理,但是只是观察对象的话严格来讲并不能够全面的观察到Spring优点,还需要进一步观察DI(依赖注入)。
在整个Spring里面可以发现,其最大的特点是:直接设置类的完整名称,而后就可以取得类的实例化对象,如果照这样的思路,Spring的核心设计思想就是反射。
构造方法注入
1,定义一个Dept.class类。
@SuppressWarnings("serial")
public class Dept implements Serializable {
private Integer deptno;
private String dname;
private String loc;
public Dept(Integer deptno,String dname,String loc){
this.deptno = deptno;
this.dname = dname;
this.loc = loc;
}
public String toString(){
return "Dept [deptno="+deptno + ",dname="+dname + ",loc=" + loc +"]";
}
}
2,修改applicationContext.xml文件,进行Dept类对象的定义
<!-- 定义一个Java类的对象,一旦定义之后在Spring启动之后就表示可以自动
实例化 -->
<bean id="dept" class="cn.mldn.vo.Dept">
<constructor-arg index="0" value="10"/>
<constructor-arg index="1" value="开发部"/>
<constructor-arg index="2" value="北京"/>
</bean>
于是这一瞬间可以发现,利用构造方法进行参数传递的时候只需要注意参数的顺序以及匹配的类型即可。
3, 定义一个测试类TestDemoA。
public class TestDemoA {
public static void main(String[] args) {
// 以后这部分的代码根本就不需要你去编写
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 将容器中已经可以使用的对象接收过来进行调用,此时与实例化对象没有任何
的关系
Dept dept = ctx.getBean("dept", Dept.class);
System.out.println(dept);
}
}
4,运行结果
之所以要用到constructor-arg ,属性的原因是类中没有无参构造了,所以如果要使用反射进行处理的话,Class类中的newInstance()将无法使用,那么此时必须明确的找到指定参数的构造方法,而后利用Constructor类来进行调用。
setter注入
现在可以发现,的确可以直接进行有参构造的调用,但是综合来讲,没有人真的这么做,因为用对象的时候更多的习惯是利用setter方法设置的。
1,更改Dept.class类
·删除代码中有参构造
·加入setter()方法;
import java.beans.ConstructorProperties;
import java.io.Serializable;
@SuppressWarnings("serial")
public class Dept implements Serializable {
private Integer deptno;
private String dname;
private String loc;
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
public void setDname(String dname) {
this.dname = dname;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String toString(){
return "Dept [deptno="+deptno + ",dname="+dname + ",loc=" + loc +"]";
}
}
2,配置相应的applicationContext.xml文件
<bean id="str" class="java.lang.String">
<constructor-arg index="0" value="北京"/>
</bean>
<!-- 定义一个Java类的对象,一旦定义之后在Spring启动之后就表示可以自动实例
化 -->
<bean id="dept" class="cn.mldn.vo.Dept">
<!-- 一旦使用了此标签,就意味者要调用类中的指定属性的setter方法 -->
<property name="deptno" value="10"/>
<property name="dname">
<value>开发部</value>
</property>
<property name="loc">
<ref bean="str"/>
</property>
</bean>
在为每个类属性设置内容的时候实例上都可以采用两种方式完成:
·value:表示设置具体的内容;
·ref:表示引用其他定义的Bean对象。
3, 定义一个测试类TestDemoB。
public class TestDemoB {
public static void main(String[] args) {
// 以后这部分的代码根本就不需要你去编写
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
// 将容器中已经可以使用的对象接收过来进行调用,此时与实例化对象没有任何的关系
Dept dept = ctx.getBean("dept", Dept.class);
System.out.println(dept);
}
}
4,运行结果
扩展:一个雇员属于一个部门,则应该创建一个雇员类,而后引用这个部门类。
1,定义一个Emp.java类
import java.io.Serializable;
@SuppressWarnings("serial")
public class Emp implements Serializable {
private Integer empno;
private String ename;
private Dept dept;
public void setDept(Dept dept){
this.dept=dept;
}
public void setEmpno(Integer empno){
this.empno = empno;
}
public void setEname(String ename){
this.ename = ename;
}
@Override
public String toString() {
return "Emp [empno=" + empno + ", ename=" + ename + ", dept=" + dept
+ "]";
}
}
2,配置applicationContext.xml文件
<bean id="dept" class="cn.mldn.vo.Dept">
<!-- 一旦使用了此标签,就意味者要调用类中的指定属性的setter方法 -->
<property name="deptno" value="10"/>
<property name="dname" value="开发部"/>
<property name="loc" value="北京"/>
</bean>
<bean id="emp" class="cn.mldn.vo.Emp">
<!-- 一旦使用了此标签,就意味者要调用类中的指定属性的setter方法 -->
<property name="empno" value="7369"/>
<property name="ename" value="SMITH"/>
<property name="dept" ref="dept"/>
</bean>
3, 定义一个测试类TestDemoC。
public class TestDemoC {
public static void main(String[] args){
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"applicationContext.xml");
Emp emp = ctx.getBean("emp",Emp.class);
System.out.println(emp);
}
}