Spring:控制反转setter方法属性注入

控制反转说明了Spring的一个特性,正常如果不用Spring,需要自己来创建对象进行实例化,而Spring的使用,让创建对象的过程变成了从Spring容器里注入,这样就把这种权利交给了Spring,控制反转可以简单地这么理解

对于Spring来实现属性依赖的注入,比如下面一个类

package com.lihuia.ioc;

/**
* Copyright (C), lihuia.com
* FileName: Demo
* Author: lihui
* Date: 2018/7/28
*/

public class Demo {

private Girl girl;

public void sayHello() {
System.out.println("Hello, " + girl.myGirl());
}

public void setGirl(Girl girl) {
this.girl = girl;
}
}

正常情况下,直接调用sayHello()方法,肯定会空指针,其中Girl类

package com.lihuia.ioc;

/**
* Copyright (C), lihuia.com
* FileName: Girl
* Author: lihui
* Date: 2018/7/28
*/

public class Girl {

public String myGirl() {
return "Lucy";
}
}

正常情况下的流程,应该是实例化一个Girl对象,传给setGirl方法,进而传递给Demo类的this.girl,最终sayHello()方法里this.girl才能调用myGirl()方法

用Spring注入,如果是通过setter方法来注入属性,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="demo" class="com.lihuia.ioc.Demo">
<property name="girl" ref="girl"></property>
</bean>
<bean id="girl" class="com.lihuia.ioc.Girl"></bean>
</beans>

首先声明一个demo bean,接着最重要的就是property标签:

(1)这里决定了使用set$name($name第一个字母大写)方法

(2)ref的值必须是是该XML里id为girl的bean,将它作为参数传递到set$name($name第一个字母大写)中

还需要声明一个girl bean,类型是Girl,这样ref的值就表示set方法传入的对象是引用了这个bean

因此整个流程就变成girl这个bean赋给了set方法,传给了this.girl,最终调用其Girl类的成员方法打印输出

可以通过TestNG验证一下

package com.lihuia.ioc;

import javax.annotation.Resource;

import org.testng.annotations.Test;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;

/**
* Copyright (C), lihuia.com
* FileName: DemoTest
* Author: lihui
* Date: 2018/7/28
*/

@ContextConfiguration(locations = {"classpath:ioc.xml"})
public class DemoTest extends AbstractTestNGSpringContextTests {

@Resource
private Demo demo;

@Test
public void testSayHello() {
demo.sayHello();
}
}

 

上面这个例子注入引用的是一个bean对象,更简单一点的是直接传一个值,那么property标签里对应的是value这个属性,比如

package com.lihuia.ioc;

/**
* Copyright (C), lihuia.com
* FileName: Demo
* Author: lihui
* Date: 2018/7/28
*/

public class Demo {

private String message;

public void sayHello() {
System.out.println("Hello, " + message);
}

public void setMessage(String message) {
this.message = message;
}
}

此时传入的是一个String类型的字符串,对于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="demo" class="com.lihuia.ioc.Demo">
<property name="message" value="Lucy"></property>
</bean>
</beans>

只需要一个demo bean,不需要在set方法里引用其他bean,而只需要传入一个具体的String类型的value即可,测试类和上面一样

发表回复