1 DI(依賴注入)簡單介紹
如果您對Spring瞭解甚少,建議先移步我的另一篇博客Spring核心功能IOC之HelloWorld因爲下面的內容是在該文章基礎上進行闡述的 ,今天我們來說一下DI(依賴注入) 其實 IOC和DI是一回事,只是看待問題的角度不一樣而已。具體區別如下
- IOC是站在Spring的角度 而DI 是站在我們的應用程序的角度
- IOC是Spring反向控制應用程序需要的資源。
- DI 是應用程序等待Spring爲其提供資源
2 注入基本類型
我們先來通過一個簡單的示例來介紹如何進行依賴注入:
我們首先在User類中添加name 和 age成員變量。併爲其提供get set方法
public class User {
private static Logger log = LoggerFactory.getLogger(User.class);
private String name;
private Integer age;
省略get and set方法
public void showUserInfo() {
log.info("name:"+name+" age:"+age);
}
}
Spring 配置文件中爲name 和 age 注入值
<bean id="user" class="cn.zhuoqianmingyue.ioc.di.User">
<property name="name" value="zhuoqianmingyue"/>
<property name="age" value="20"/>
</bean>
進行測試:
public class UserPropertyDITest {
@Test
public void diBasePropertyXml() {
ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-di-context.xml");
User user = (User)appliction.getBean("user");
user.showUserInfo();
}
}
我們爲指定的bean的注入基本類型具體操作步驟:
- 爲成員變量提供set方法 (get方法可以沒有但是一定要有set方法)
- 在配置文件中通過添加property 標籤 指定成員變量name和value(成員變量的值)
需要注意的是這裏property 標籤標籤中的name和set方法的name一定要一致 否則會導致注入失敗
我們將setName 改成 setName1 會報如下異常:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘user’ defined in class path resource [ioc-di-context.xml]: Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property ‘name’ of bean class [cn.zhuoqianmingyue.ioc.di.User]: Bean property ‘name’ is not writable or has an invalid setter method. Did you mean ‘age’, or ‘name1’?
at
3 注入引用類型
有的時候我們的成員變量可能是一個引用類型,也就是說我們的類中有類成員變量。爲一個Bean注入引用類型具體操作如下:
- 爲類成員變量提供set方法 (get方法可以沒有但是一定要有set方法)
- 在Spirng配置文件中把我們引用的類配置成Spring的Bean
- 在Spirng配置文件中通過property標籤的ref來指定我們的引用Bean的id
具體代碼操作流程如下:
我們還是用User類來進行介紹,首先爲我們的User 添加一個國家的成員變量。
具體代碼如下:
public class Country {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void countryInfo() {
System.out.println(name);
}
}
//這個只是示例代碼
public class User {
private static Logger log = LoggerFactory.getLogger(User.class);
private String name;
private Integer age;
private Country country;
}
Sping配置文件添加代碼如下:
<bean id="country" class="cn.zhuoqianmingyue.ioc.di.Country">
<property name="name" value="CHINA"/>
</bean>
<bean id="user" class="cn.zhuoqianmingyue.ioc.di.User">
<property name="country" ref="country"></property>
</bean>
進行測試:
@Test
public void diClassProperty() {
ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-di-context.xml");
User user = (User)appliction.getBean("user");
Country country = user.getCountry();
log.info("country:"+country.getName());
}
4 注入List
關於Bean注入List操作步驟和上面基本是一致的不同的是
注入List 需要通過list標籤 list中的元素通過value標籤來進行值的設置,
<property name="set方法的名稱">
<list>
<value>注入的值</value>
<value>注入的值</value>
</list>
</property>
如果List中元素是引用類型具體寫法如下:
<property name="set方法的名稱">
<list>
<ref bean="引用bean的id" />
<ref bean="引用bean的id"/>
</list>
</property>
具體代碼操作如下:
用戶類中添加名稱爲address的list成員屬性
public class User {
private List<String> address;
}
Spring配置文件配置如下:
<bean id="user" class="cn.zhuoqianmingyue.ioc.di.User">
<property name="address">
<list>
<value>北京</value>
<value>河北</value>
</list>
</property>
</bean>
進行測試:
@Test
public void diListProperty() {
ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-di-context.xml");
User user = (User)appliction.getBean("user");
List<String> address = user.getAddress();
address.forEach((str)->{
System.out.print(str+" ");
});
}
5 注入Set
關於Bean注入Set操作步驟和上面基本是一致的不同的是
Bean 注入Set 需要通過set標籤 set中的元素通過value標籤來進行值的設置。
<property name="set方法的名稱">
<set>
<value>注入的值</value>
<value>注入的值</value>
</set>
</property>
如果Set中的元素是引用類型具體寫法如下:
<property name="set方法的名稱">
<set>
<ref bean="引用bean的id" />
<ref bean="引用bean的id"/>
</set>
</property>
具體代碼操作如下:
用戶類中添加 名稱爲address2的Set成員變量
public class User {
private Set<String> address2;
}
Spring配置文件配置如下:
<bean id="user" class="cn.zhuoqianmingyue.ioc.di.User">
<property name="address2">
<set>
<value>北京</value>
<value>河北</value>
</set>
</property>
</bean>
進行測試:
@Test
public void diSetProperty() {
ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-di-context.xml");
User user = (User)appliction.getBean("user");
Set<String> address2 = user.getAddress2();
address2.forEach((str)->{
System.out.print(str+" ");
});
}
6 注入Map
關於Bean注入Map操作步驟和上面基本是一致的不同的是
Bean 注入Map 需要通過map標籤 map中的元素通過entry 標籤來進行key 和value值的設置。
<property name="set方法的名稱">
<map>
<entry key=""注入的key值" value="引用bean的id"/>
<entry key="注入的key值" value="引用bean的id"/>
</map>
</property>
如果map中value的值是引用類型具體寫法如下:
<property name="set方法的名稱">
<map>
<entry key="注入的key值" value-ref="注入的value值" />
<entry key="注入的key值" value-ref="注入的value值" />
</map>
</property>
具體代碼操作如下:
用戶類中添加 名稱爲addressMap的Map成員變量
public class User {
private static Logger log = LoggerFactory.getLogger(User.class);
private Map<String,String> addressMap;
}
Spring配置文件配置如下:
<property name="addressMap">
<map>
<entry key="BEIJING" value="北京"/>
<entry key="HEBEI" value="河北"/>
</map>
</property>
進行測試:
@Test
public void diMapProperty() {
ApplicationContext appliction = new ClassPathXmlApplicationContext("ioc-di-context.xml");
User user = (User)appliction.getBean("user");
Map<String, String> addressMap = user.getAddressMap();
addressMap.forEach((k, v)->{
System.out.print("key:"+k+" value:"+v);
});
}