Spring之IOC(DI)
控制反轉(zhuǎn) Inversion of Control
依賴注入 Dependency Injection and
下面通過(guò)一個(gè)例子學(xué)習(xí)spring的IOC。
一個(gè)例子
源代碼目錄結(jié)構(gòu)如下:
main
service
UserService
dao
UserDao(接口)
UserDaoImpl
model
User
beans.xml
假如我們想實(shí)現(xiàn)一個(gè)如下功能:調(diào)用service層的UserService保存用戶數(shù)據(jù)。在UserService中調(diào)用UserDao存入數(shù)據(jù)庫(kù)。
在沒(méi)有spring之前萧福,我們?cè)趕ervice層使用dao層功能的時(shí)候需要一個(gè)實(shí)現(xiàn)了UserDao的實(shí)例對(duì)象琴许,即顯式new一個(gè)對(duì)象逢享。
spring是怎么幫我們做的呢?

如圖,我們只需要在配置文件中配置相關(guān)信息遭顶,spring容器會(huì)自動(dòng)替我們創(chuàng)建對(duì)象。
XML配置文件如下:
<bean id="user" class="main.dao.UserDaoImpl">
</bean>
<bean id="userService" class="main.service.UserService">
<property name="userDao" ref="user"></property>
</bean>
test文件
@Test
public void test() {
// 通過(guò)指定XML文件得到一個(gè)ApplicationContext對(duì)象
ApplicationContext context = new ClassPathXmlApplicationContext("main/beans.xml");
// 通過(guò)配置文件中的bean得到一個(gè)UserService對(duì)象
UserService service = (UserService) context.getBean("userService");
service.add();
}
spring是怎么幫我們做的呢泪蔫?首先解析配置文件棒旗,通過(guò)反射得到所有的bean對(duì)象,調(diào)用UserService的setUserDao方法撩荣,注入U(xiǎn)serDao到userService中铣揉。
** 上述例子通過(guò)XML配置userService和userDao之間的依賴關(guān)系,我們也可通過(guò)注解的方式配置兩者之間的關(guān)系餐曹。 **
首先我們需要在配置文件中加入一行配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:annotation-config/>
<context:annotation-config/>
要記得引入context的約束文件逛拱。
接著用注解@Autowired,@Autowired放在如下地方:
- setter
- 構(gòu)造方法
- 接口
在我們的例子中:
public class UserService {
private UserDao userDao;
@Autowired
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
public void add () {
userDao.save(new User());
}
}
@Autowired 注解默認(rèn)按類型在bean容器中尋找需要的UserDao台猴,如果UserDao有多個(gè)實(shí)現(xiàn)怎么辦朽合?
這個(gè)時(shí)候需要另一個(gè)注解@Qualifier縮小范圍俱两。
它的使用如下:
@Autowired
@Qualifier("main")
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
在XML中配置bean的qualifier屬性
<bean id="user" class="main.dao.UserDaoImpl">
<qualifier value="main"></qualifier>
</bean>
其實(shí)bean的name是默認(rèn)的qualifier value,我們也可以用id代替qualifier 元素曹步。
前面的先放一下宪彩,來(lái)看一段官方文檔:
Most examples in this chapter use XML to specify the configuration metadata that produces each BeanDefinition within the Spring container. The previous section demonstrates how to provide a lot of the configuration metadata through source-level annotations. Even in those examples, however, the "base" bean definitions are explicitly defined in the XML file, while the annotations only drive the dependency injection. This section describes an option for implicitly detecting the candidate components by scanning the classpath.Candidate components are classes that match against a filter criteria and have a corresponding bean definition registered with the container. This removes the need to use XML to perform bean registration, instead you can use annotations (for example @Component), AspectJ type expressions, or your own custom filter criteria to select which classes will have bean definitions registered with the container.
在配置文件中加入這句:
<context:component-scan base-package="org.example"/>
一個(gè)@Component注解即可讓spring自動(dòng)尋找需要的bean。