IoC中文译为控制反转,也可以叫做DI(依赖注入),控制反转模式的基本概念是:不直接创建对象,但是描述创建他们的方式。在工程中使用该Bean时,由Spring容器创建Bean的实例。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一个服务。
Sping框架的控制反转有3种形式注入:接口注入,Setter注入,和构造器注入。
3种注入方式各有特点。接口注入在灵活性,易用性上不如其他2中注入模式,Setter注入方式更加直观,明显,开发人员更容易理解,接收。构造器注入能够方便的控制依赖关系的注入顺序,更适用于依赖关系中无需变化的Bean,组件内部的依赖关系完全透明,更符合高内聚的原则。
下属练习代码主要针对的就是Setter注入形式;
练习代码1:Setter注入方式的简单练习:包括一般成员变量和依赖关系的一般对象注入
//编写javaBean,练习使用Spring ioc中依赖注入的setter方法注入
package com.liuxuanjie4;
public class User {
//两个成员变量
String name = null;
int id = 0;
public void printInfo()
{
System.out.println("该成员的名字为:"+this.name);
System.out.println("该成员的编号为:"+this.id);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
//编写javaBean仍旧是对Setter注入方法进行测试,一般对象注入
package com.liuxuanjie4;
public class UserManager {
private User user = null;
public void printInfo()
{
this.user.printInfo();
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
//编写测试类,对setter方法的依赖注入进行测试练习
package com.liuxuanjie4;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String args[])
{
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
User user1 = (User)factory.getBean("user1");
user1.printInfo();
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.printInfo();
}
}
配置文件相关的显示
<!-- 通过Setter方法注入 ,一般成员变量-->
<bean id="user1" class="com.liuxuanjie4.User">
<property name="name" value="jilin"></property>
<property name="id" value="1001"></property>
</bean>
<!-- 通过Setter方法注入,一般对象实例 -->
<bean id="userManager" class="com.liuxuanjie4.UserManager">
<property name="user" ref="user1"></property>
</bean>
程序代码简单测试结果显示:
练习代码2:通过构造函数注入属性值
//编写一个javabean,练习使用Spring ioc的构造函数注入方式(Setter注入)
package com.liuxuanjie3;
public class JavaBean {
private String name,phone;
private int id;
public JavaBean(String name,String phone,int id)
{
this.name = name;
this.phone = phone;
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
//测试类,去操作spring配置文件的依赖注入获取容器内的javabean示例
package com.liuxuanjie3;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String args[])
{
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
JavaBean javaBean = (JavaBean)factory.getBean("javaBean");
System.out.println("第一个构造函数下的javabean信息如下:");
System.out.println("姓名:"+javaBean.getName());
System.out.println("电话:"+javaBean.getPhone());
System.out.println("编号:"+javaBean.getId());
JavaBean javaBean2 = (JavaBean)factory.getBean("javaBean2");
System.out.println("第二个构造函数下的javabean信息如下:");
System.out.println("姓名:"+javaBean2.getName());
System.out.println("电话:"+javaBean2.getPhone());
System.out.println("编号:"+javaBean2.getId());
}
}
配置文件相关bean的设置:
<!-- 构造函数注入示例,没有index,相对顺序即为构造函数的相对顺序 -->
<bean id="javaBean" class="com.liuxuanjie3.JavaBean">
<constructor-arg value="jilin"></constructor-arg>
<constructor-arg value="110120"></constructor-arg>
<constructor-arg value="1101"></constructor-arg>
</bean>
<!-- 构造函数注入示例,有index,下标从0开始 -->
<bean id="javaBean2" class="com.liuxuanjie3.JavaBean">
<constructor-arg index="0" value="changchun"></constructor-arg>
<constructor-arg index="1" value="119120"></constructor-arg>
<constructor-arg index="2" value="1002"></constructor-arg>
</bean>
程序测试结果简单显示:
练习代码3;使用面向接口的编程技术,仍然是Setter注入,根据这个例子理解这样的好处!
//本例子为使用面向接口的编程技术,然后使用spring的注入进行操作
package com.liuxuanjie2;
public interface UserDao {
public void save(String name,String password);
}
package com.liuxuanjie2;
public class UseOracleImplement implements UserDao{
@Override
public void save(String name, String password) {
System.out.println("使用了oracle来实现具体的业务逻辑!");
}
}
package com.liuxuanjie2;
public class UseMysqlImplement implements UserDao{
public void save(String name,String password)
{
System.out.println("使用了mysql去实现具体的业务逻辑!");
}
}
//编写管理类,来具体调用其使用的是哪一个具体实现类
package com.liuxuanjie2;
public class Manager {
UserDao dao = null;
public void save(String name,String password)
{
dao.save(name, password);
}
public UserDao getDao() {
return dao;
}
public void setDao(UserDao dao) {
this.dao = dao;
}
}
//编写测试类,来测试之前利用面向接口的编程技术以及使用spring的依赖注入bean
package com.liuxuanjie2;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String args[])
{
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Manager manager = (Manager)factory.getBean("manager");
manager.save("jilin", "123456");
}
}
配置文件相关设置
<!-- 使用xml配置bean,使bean可以用spring容器来管理! -->
<bean id="hello" class="com.liuxuanjie.Hello"></bean>
<bean id="mysql" class="com.liuxuanjie2.UseMysqlImplement"></bean>
<bean id="oracle" class="com.liuxuanjie2.UseOracleImplement"></bean>
<!-- manager的dao属性依赖Spring来注入,可以在程序中无需改变代码,就可以注入不同的实例 -->
<!-- 此处注入的是使用mysql的实现类,如果要是用oracle只需要改变ref的注入即可 -->
<bean id="manager" class="com.liuxuanjie2.Manager">
<property name="dao" ref="oracle"></property>
</bean>
代码简单测试显示结果如下: