前言
平常的java開發中,程序員在某個類中需要依賴其它類的方法,則通常是new
一個依賴類再調用類實例的方法,這種開發存在的問題是new
的類實例不好統一管理,spring提出了依賴注入的思想,即依賴類不由程序員實例化,而是通過spring容器幫我們new
指定實例并且將實例注入到需要該對象的類中。依賴注入的另一種說法是“控制反轉”,通俗的理解是:平常我們new
一個實例,這個實例的控制權是我們程序員,而控制反轉是指new
實例工作不由我們程序員來做而是交給spring容器來做。
在Spring中依賴注入有四種方式
1、set注入(通常也叫屬性注入)
2、構造函數注入
3、接口注入(這個現在基本不用)
4、注解注入(@Autowire)
下面對set方法注入,構造函數注入,以及注解注入的用法舉例說明。
1、set方法注入(屬性注入)
UserDao.java
1
2
3
4
5
|
public class UserDao{ public void inserUser(User user){ //具體邏輯省略 } } |
UserService.java
1
2
3
|
public Interface UserService{ void inserUser(User user); } |
UserServiceImpl.java
1
2
3
4
5
6
7
8
9
|
public class UserServiceImpl implements UserService{ private UserDao userDao; public void setUserDao(UserDao userDao){ this .userDao = userDao; } public void insertUser(User user){ userDao.insert(user); } } |
Spring配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<?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-2.5.xsd http: //www.springframework.org/schema/context http: //www.springframework.org/schema/context/spring-context-2.5.xsd "> <!--省略一些無關的配置書寫--> <bean id= "userDao" class = "UserDao" ></bean> <bean id= "userService" class = "UserServiceImpl" > <property name= "userDao" ref= "userDao" > </bean> </beans> |
以上就可以把userDao注入到UserServiceImpl中
2、構造函數注入
User.java
1
2
3
4
5
6
7
8
9
10
|
public class User{ //為了簡便,就寫兩個屬性 private String name; private Integer age; //關于name,age的getter/setter方法省略 public User(String name, int age){ this .name = name; this .age = age; } } |
現在通過Spring配置文件來注入這User這個對象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<? 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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd "> <!--省略一些無關的配置書寫--> < bean id = "user" class = "User" > <!--構造函數參數的下標從0開始(避免出現多個構造函數具有相同的參數個數)--> < constructor-arg type = "java.lang.String" index = "0" value = "zhangsan" /> < constructor-arg type = "java.lang.Integer" index = "1" value="20> </ bean > </ beans > |
以上就可以將屬性值注入到User對象中。當然如果想以set方法注入的例子話,其實也一樣。就是在UserServiceImpl
需要構造函數,形參就是userDao了,就不需要setter
方法了。
那么關于其Spring的配置文件的書寫應該改成這樣
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<? 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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd "> <!--省略一些無關的配置書寫--> < bean id = "userDao" class = "UserDao" ></ bean > < bean id = "userService class=" UserServiceImpl"> <!--構造函數參數的下標從0開始(避免出現多個構造函數具有相同的參數個數)--> < constructor-arg index = "0" ref = "userDao" > </ bean > </ beans > |
這樣也能實現上面set方法注入達到的效果
3、注解注入
我沒試過在這些類上不加@Component,@Service,@Controller
等直接@Autowire
,是否能成功注入,不過養成一個比較好的編程習慣,建議在相應的層次加上相應的注解。如下例子中UserDao屬于Modul層,在Spring中可以用@Component
注解
UserDao.java
1
2
3
4
5
6
|
@Component public class UserDao{ public void inserUser(User user){ //具體邏輯省略 } } |
UserService.java
1
2
3
|
public Interface UserService{ void inserUser(User user); } |
UserServiceImpl.java
1
2
3
4
5
6
7
8
9
|
//引入相應的Spring包 @Service public class UserServiceImpl implements UserService{ @Autowire private UserDao userDao; public void insertUser(User user){ userDao.insert(user); } } |
Spring對應的配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
<? 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-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd "> <!--省略一些無關的配置書寫--> <!--*代表對所有的包進行掃描,在實際開發中可以根據涉及到注解組件的包進行掃描--> < context:component-scan base-package = "*" > <!-- 開啟組件掃描 --> </ context:component-scan > < context:annotation-config > <!--開啟注解處理器--> </ context:annotation-config > < bean id = "userDao" class = "UserDao" ></ bean > < bean id = "userService" class = "UserServiceImpl" /> </ beans > |
不過在開發過程中既開啟了set方法注入,有開啟了注解注入的話,Spring會首選set注入的,所以不忘了提供相應的set方法的,否則會出現失敗。
通過比較,注解注入要比其余注入要方便的多,代碼和配置文件也寫的少,在開發的過程中還是建議使用注解注入。
總結
以上就是關于Spring中依賴注入的幾種方式的全部介紹,希望能對大家的學習或者工作帶來一定的幫助,如果有疑問大家也可以留言交流,謝謝大家對服務器之家的支持。