IOC 和 DI 自动装配

IOC (Inversion Of Controll 控制反转)

什么是IOC?

对象之间的依赖关系由容器来建立。

什么是DI? (Dependency Injection 依赖注入)

容器通过调用set方法或者构造器来建立对象之间的依赖关系。
注: IOC是目标,而DI是手段。 

依赖注入的两种方式

1.set注入

三个实现类:

package ioc;

public class A {

	private IB param;

	public void setParam(IB param) {
		System.out.println("setParam");
		this.param = param;
	}
	
	public A() {
		System.out.println("A()");
	}

	public void execute(){
		System.out.println("execute");
		param.f1();
	}
}
package ioc;

public class B implements IB{

	public B() {
		System.out.println("B()");
	}

	public void f1(){
		System.out.println("B's f1()");
	}
}
package ioc;

public class C implements IB{

	public C() {
		System.out.println("C()");
	}
	
	public void f1(){
		System.out.println("C's f1()");
	}

}
接口:
package ioc;

public interface IB {
	public void f1();
}
配置文件:

<bean id="b1" class="ioc.B"></bean>
	<bean id="c1" class="ioc.C"></bean>
	
	<!-- property元素:表示使用set方法来注入依赖关系 
		 name属性:指定属性名称
		 ref属性:指定属性的值(被注入的bean的ID)
	-->
	<!-- name="abc" 会将a改为大写,调用setAbc()方法 相当于bean属性 -->
	<bean id="a1" class="ioc.A">
	  <property name="param" ref="c1"></property>
	</bean>
测试文件:

@Test
	//测试set方式注入
	public void test4(){
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext("ioc.xml");
		A a1 = ac.getBean("a1",A.class);
		a1.execute();
		/**
		 * 将B或C注入A的bean中(调用了A类中的set方法)
		 * 输出结果:
		 * B()
		 * C()
		 * A()
		 * setParam
		 * execute
		 * C's f1()  此处根据配置文件A注入的元素不同有不同的输出
		 */
		//分析步骤:由于A、B、C单例,先创建A、B、C对象,使用A中set()方法将需注入对象注入到A中
		//调用A中的execute()方法,在注入时候使用接口,这样就只修改配置文件即可
	}

2.构造器注入

两个实现类

package ioc2;

public class B {

	public B() {
		System.out.println("B()");
	}
	
	public void f1(){
		System.out.println("B's f1()");
	}

}
package ioc2;

public class A {

	private B b;
	public A() {
		System.out.println("A()");
	}
	
	public A(B b) {
		System.out.println("A(B)");
		this.b = b;
	}

	public void execute(){
		System.out.println("execute()");
		b.f1();
	}

}
配置文件:

<bean id="b1" class="ioc2.B"></bean>
	
	<!-- constructor-arg元素:用来配置构造器方式注入 
		 index属性指定参数的下标(从0开始)
		 ref属性:被注入bean的ID
	-->
	<bean id="a1" class="ioc2.A">
	  <constructor-arg index="0" ref="b1"></constructor-arg>
	</bean>
测试文件:
@Test
	public void test1(){
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		A a1 = ac.getBean("a1",A.class);
		a1.execute();
		/**
		 * B对象通过B的无参构造方法创建,A通过A的有参构造创建,并将B传入A
		 * 输出结果:
		 * B()  --创建B对象
		 * A(B) --创建A对象,并将B注入A
		 * execute() -- 调用execute方法输出
		 * B's f1()
		 * 一般情况使用set注入,构造器注入使用较少
		 */
	}

自动装配 (了解)

什么是自动装配?

容器依据某些规则,自动建立对象之间的依赖关系。
注:默认情况下,容器禁止自动装配。

代码如下:

package ioc2;

public class Waiter {

	public Waiter() {
		System.out.println("Waiter()");
	}

}
package ioc2;

public class Resturatant {

	private Waiter wt;
	
	public Resturatant() {
		System.out.println("Resturatant()");
	}

	public void setWt(Waiter wt) {
		System.out.println("setWt()");
		this.wt = wt;
	}

	@Override
	public String toString() {
		return "Resturatant [wt=" + wt + "]";
	}

}
配置文件:

<!-- 自动装配 -->
	<bean id="wt" class="ioc2.Waiter"></bean>
	
	<!-- autowire属性:自动装配(默认值为no,不自动装配)
		   该属性有如下三个值:
		 byName属性:容器根据属性名查找对应的bean的ID(属性名要和bean的ID相同),然后调用set方法完成注入,
		   如果找不到对应的bean,则注入null,不可能找到多个bean,应为id唯一
		 
		 byType属性:容器根据属性的类型查找对应的bean,调用对应的set方法来完成注入
		    如果找不到对应的bean,则注入null,如果找到多个bean,出错
		    
		 constructor:与byType类似,只不过通过构造器进行注入
	 -->
	<bean id="rest" class="ioc2.Resturatant" autowire="byType"></bean>
测试文件:

@Test
	//测试自动装配
	public void test3(){
		ApplicationContext ac = 
				new ClassPathXmlApplicationContext("applicationContext.xml");
		Resturatant rest = ac.getBean("rest",Resturatant.class);
		System.out.println(rest);
		/**
		 * autowire="byName"输出结果:
		 * Waiter()
		 * Resturatant()
		 * setWt()
		 * Resturatant [wt=ioc2.Waiter@e6a65d]
		 * 如果找不到对应的bean,则注入null
		 */
		/**
		 * autowire="byName"输出结果:
		 * Waiter()
		 * Resturatant()
		 * setWt()
		 * Resturatant [wt=ioc2.Waiter@1553d26]
		 * 如果找不到对应的bean,则注入null,找到多个则报错
		 */
		/**
		 * constructor:与byType类似,只不过通过构造器进行注入
		 */
		//自动装配时使用byName最好,最多注入null,且不会报错
	}



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荒--

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值