Spring依賴注入及使用註解注入bean
Spring 最認同的技術是控制反轉的依賴注入(DI)模式。控制反轉(IoC)是一個通用的概念,它可以用許多不同的方式去表達,依賴注入僅僅是控制反轉的一個具體的例子。
IOC : Inverse Of Control 控制反轉
作用:建立物件 並且維護物件之間的依賴關係
DI :依賴注入 Spring支援的注入方式
構造方法注入
setter注入
註解注入
實現原理:反射
IOC:Inversion of Control,控制反轉。指的是物件的建立權反轉(交給)給Spring,其作用是實現了程式的解耦合。也可這樣解釋:獲取物件的方式變了。物件建立的控制權不是“使用者”,而是“框架”或者“容器”。
DI:Dependency Injection 依賴注入,其實是當一個bean例項引用到了另外一個bean例項時spring容器幫助我們建立依賴bean例項並注入(傳遞)到另一個bean中,如上述案例中的UserServiceImpl類依賴於UserDao的實現類UserDaoImpl,Spring容器會在建立UserService的實現類和UserDao的實現類後,把UserDao的實現類注入UserService例項中,有關依賴注入後面還要詳細講的。
1. 屬性(設值)注入: 〈property〉
指 IoC 容器通過成員變數的 setter 方法來注入被依賴物件。這種注入方式簡單、直觀,因而在 Spring 依賴注入裡大量使用。
mvc 類
public class User { private int id; private String username; private String password; private Map<String,String> map = new HashMap<String,String>(); private List<String> list = new ArrayList<>(); // Set 類同 List ... 必須提供 setter 方法 } public class UserServiceImpl implements UserService{ //面向介面程式設計 private UserDao userDao; public void setUserDao(UserDao userDao) { this.userDao = userDao; } ... 必須提供 setter 方法 }
配置檔案:
<?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="user" class="cn.jq.springdemo.model.User">
<property name="id" value="5"></property>
<property name="username" value="admin"></property>
<property name="password" >
<value><![CDATA[>123<admin><]]></value>
</property>
<property name="map">
<map>
<entry key="java" value="80"></entry>
<entry key="spring" value="85"></entry>
</map>
</property>
<property name="list">
<list>
<value>lisi</value>
<value>zs</value>
</list>
</property>
</bean>
<bean id="userDao" class="cn.jq.springdemo.dao.UserDaoImpl"></bean>
<bean id="userService"
class="cn.jq.springdemo.service.UserServiceImpl">
<property name="userDao" ref="userDao"></property>
</bean>
</beans>
測試類:
@Test
public void test() {
// 1.初始化ioc容器(裝物件的容器)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.從容器中獲得建立好的物件
User user = context.getBean("user", User.class);
System.out.println(user);
}
-------
User [id=5, username=admin, password=>123<admin><, map={java=80, spring=85}, list=[lisi, zs]]
2. 構造注入:〈constructor-arg〉
指利用構造器來設定依賴關係的方式。通俗來說,就是驅動Spring在底層以反射方式執行帶指定引數的構造器,當執行帶引數的構造器時,就可利用構造器引數對成員變數執行初始化——這就是構造注入的本質。
mvc 類:
public class UserServiceImpl implements UserService{
//面向介面程式設計
private UserDao userDao;
private User user;
private int num;
private String str;
public UserServiceImpl(UserDao userDao, User user, int num, String str) {
super();
this.userDao = userDao;
this.user = user;
this.num = num;
this.str = str;
}
}
配置檔案:
<?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="user" class="cn.jq.springdemo.model.User">
<property name="id" value="5"></property>
<property name="username" value="admin"></property>
</bean>
<bean id="userDao" class="cn.jq.springdemo.dao.UserDaoImpl"></bean>
<bean id="userService" class="cn.jq.springdemo.service.UserServiceImpl">
<constructor-arg type="cn.jq.springdemo.dao.UserDao" ref="userDao"></constructor-arg>
<constructor-arg index="1" ref="user"></constructor-arg>
<constructor-arg type="int" value="20"></constructor-arg>
<constructor-arg type="java.lang.String" value="adminstr"></constructor-arg>
</bean>
</beans>
name - 引數的名字 或者 index - 引數的索引位置 從0開始(注意:構造方法的引數順序)
ref - 指引用型別,指向另外一個bean標籤的id
vlaue - 指簡單型別的值
測試類:
@Test
public void test() {
// 1.初始化ioc容器(裝物件的容器)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.從容器中獲得建立好的物件
UserServiceImpl userService = context.getBean("userService",UserServiceImpl.class);
System.out.println(userService);
}
-------
UserServiceImpl [[email protected], user=User [id=5, username=admin, password=null, map={}, list=[]], num=20, str=adminstr]
兩種注入方式的對比
setter注入優點:
- 與傳統的JavaBean的寫法更相似,程式開發人員更容易理解、接受。通過setter方法設定依賴關係顯得更加直觀、自然。
- 對於複雜的依賴關係,如果採用構造注入,會導致構造器過於臃腫,難以閱讀。Spring在建立Bean例項時,需要同時例項化其依賴的全部例項,因而導致效能下降。而使用設值注入,則能避免這些問題。
- 尤其在某些成員變數可選的情況下,多引數的構造器更加笨重。
構造注入優點:
- 構造注入可以在構造器中決定依賴關係的注入順序,優先依賴的優先注入。
- 對於依賴關係無需變化的Bean,構造注入更有用處。因為沒有setter方法,所有的依賴關係全部在構造器內設定,無須擔心後續的程式碼對依賴關係產生破壞。
- 依賴關係只能在構造器中設定,則只有元件的建立者才能改變元件的依賴關係,對元件的呼叫者而言,元件內部的依賴關係完全透明,更符合高內聚的原則。
注意:
建議採用settter注入為主,構造注入為輔的注入策略。對於依賴關係無須變化的注入,儘量採用構造注入;而其他依賴關係的注入,則考慮採用設值注入。
二. Spring的自動裝配(對於大型的應用,不鼓勵使用自動裝配)
Spring自動裝配可通過 <beans/>
元素的 default-autowire
屬性指定,該屬性對配置檔案中所有的Bean起作用;
也可通過對 <bean/>
元素的 autowire
屬性指定,該屬性只對該Bean起作用。
模式 | 描述 |
---|---|
no | 這是預設的設定,它意味著沒有自動裝配,你應該使用顯式的bean引用來連線。你不用為了連線做特殊的事。在依賴注入章節你已經看到這個了。 |
由屬性名自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byName。然後嘗試匹配,並且將它的屬性與在配置檔案中被定義為相同名稱的 beans 的屬性進行連線。 | |
由屬性資料型別自動裝配。Spring 容器看到在 XML 配置檔案中 bean 的自動裝配的屬性設定為 byType。然後如果它的型別匹配配置檔案中的一個確切的 bean 名稱,它將嘗試匹配和連線屬性的型別。如果存在不止一個這樣的 bean,則一個致命的異常將會被丟擲。 | |
類似於 byType,但該型別適用於建構函式引數型別。如果在容器中沒有一個建構函式引數型別的 bean,則一個致命錯誤將會發生。 | |
autodetect | Spring首先嚐試通過 constructor 使用自動裝配來連線,如果它不執行,Spring 嘗試通過 byType 來自動裝配。 |
常用兩種模式:
byTpye模式:Spring容器會基於反射檢視bean定義的類,然後找到與依賴型別相同的bean注入到另外的bean中,這個過程需要藉助setter注入來完成,因此必須存在set方法,否則注入失敗。
byName模式:此時Spring只會嘗試將屬性名與bean名稱進行匹配,如果找到則注入依賴bean。
mvc 類
public class UserServiceImpl implements UserService{
private UserDao userDao; //面向介面程式設計
private User user;
... 必須提供 setter 方法
}
配置檔案:
<?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="user" class="cn.jq.springdemo.model.User">
<property name="id" value="5"></property>
<property name="username" value="admin"></property>
<property name="password" >
<value><![CDATA[>123<admin><]]></value>
</property>
</bean>
<bean id="userDao" class="cn.jq.springdemo.dao.UserDaoImpl"></bean>
<!--自動裝配userService類成員屬性
autowire - byName 自動裝配和成員屬性名稱相同的bean 呼叫的是setter方法注入
注意: 確保成員屬性的 名稱規範 有對應setter方法 還有就是bean的id和成員屬性的名稱相同
byType 根據型別自動裝配
同一種類型的 bean 只能配置一個唯一的標籤
-->
<bean id="userService" class="cn.jq.springdemo.service.UserServiceImpl" autowire="byName">
</bean>
</beans>
測試類:
@Test
public void test() {
// 1.初始化ioc容器(裝物件的容器)
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//2.從容器中獲得建立好的物件
UserServiceImpl userService = context.getBean("userService",UserServiceImpl.class);
System.out.println(userService);
}
------
UserServiceImpl [[email protected], user=User [id=5, username=admin, password=>123<admin><, map={}, list=[]]]
如果Spring容器中沒有找到可以注入的例項bean時,將不會向依賴屬性值注入任何bean,
這時依賴bean的屬性為 null 或 基本型別預設值。
三. 使用註解注入bean
Spring 使用註解,通過"@XXX"的方式,讓註解與Java Bean緊密結合,既大大減少了配置檔案的體積,又增加了Java Bean的可讀性與內聚性。
首先,在 applicationContext.xml 核心配置檔案中需要用到 context 名稱空間,然後使用 context:component-scan 標籤告訴spring框架,配置了註解的類的位置。
base-package: 指定spring掃描註解的類所在的包(包含子包)。當需要掃描多個包的時候,可以使用逗號分隔。
<!-- 使用註解驅動 自動註冊bean -->
<context:component-scan base-package="cn.jq.springdemo"></context:component-scan>
1. 註解說明:
Component最初spring框架設計的,後來為了標識不同程式碼層,衍生出Controller,Service,Repository三個註解 作用相當於配置檔案的bean標籤,被註解的類,spring始化時,就會建立該物件
只能新增在類上 不能新增在抽象類和介面上:
@Controller 用於標註控制層元件,即web業務層。
@Service 用於標註業務層元件,即service層。
@Repository(value="userDao") 用於標註資料訪問元件,即dao層。
@Component 泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註。
@Scope(scopeName="singleton") 用於指定scope作用域的(控制類生成的時候採用單例還是多例)
註解屬性 value 對應的是建立的物件的名字 和id相同 (預設配置下預設的名字為 類名首字母小寫)
定義在類的 屬性欄位上:
@Value(value="112") 給簡單型別屬性賦值,可以用在方法上或屬性上
@Resource(name="user") 給物件引用型別賦值,該值user類必須已經宣告(在配置檔案中已經配置,或在類對應中已經註解)
說一下@Resource 的裝配順序:
(1)、@Resource後面沒有任何內容,預設通過name屬性去匹配bean,找不到再按type去匹配
(2)、指定了name或者type則根據指定的型別去匹配bean
(3)、指定了name和type則根據指定的name和type去匹配bean,任何一個不匹配都將報錯
@Autowired 自動裝配,給物件引用型別賦值,其作用是為了消除程式碼Java程式碼裡面的getter/setter與bean屬性中的property。
@Autowired(required=false) :Spring容器找不到屬性就丟擲異常,若設定required=false即不再丟擲異常而認為屬性為null
實現類要是有多個,此時可以使用@Qualifier註解來指定你要注入Bean的名稱
@Autowired
@Qualifier("student2")
2. @Autowired和@Resource兩個註解的區別:
1)、@Autowired預設按照byType方式進行bean匹配,@Resource預設按照byName方式進行bean匹配
2)、@Autowired是Spring的註解,@Resource是J2EE的註解,
3. Spring常用註解彙總
@Configuration把一個類作為一個IoC容器,它的某個方法頭上如果註冊了@Bean,就會作為這個Spring容器中的Bean。
@Scope註解 作用域
@Lazy(true) 表示延遲初始化
@Service用於標註業務層元件、
@Controller用於標註控制層元件(如struts中的action)
@Repository用於標註資料訪問元件,即DAO元件。
@Component泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註。
@Scope用於指定scope作用域的(用在類上)
@PostConstruct用於指定初始化方法(用在方法上)
@PreDestory用於指定銷燬方法(用在方法上)
@DependsOn:定義Bean初始化及銷燬時的順序
@Primary:自動裝配時當出現多個Bean候選者時,被註解為@Primary的Bean將作為首選者,否則將丟擲異常
@Autowired 預設按型別裝配,如果我們想使用按名稱裝配,可以結合@Qualifier註解一起使用。如下:
@Autowired @Qualifier("personDaoBean") 存在多個例項配合使用
@Resource預設按名稱裝配,當找不到與名稱匹配的bean才會按型別裝配。
@PostConstruct 初始化註解
@PreDestroy 摧毀註解 預設 單例 啟動就載入
@Async非同步方法呼叫
四、泛型依賴注入(spring 4.x以上版本才有)
泛型依賴注入就是允許我們在使用spring進行依賴注入的同時,利用泛型的優點對程式碼進行精簡,將可重複使用的程式碼全部放到一個類之中,方便以後的維護和修改。同時在不增加程式碼的情況下增加程式碼的複用性。
BaseDao<T> 類: 泛型方法引數控制
BaseService<T> 類: 物件引用屬性 baseDao控制,泛型注入
相關推薦
Spring注入:配置注入(set注入和構造器注入)與註解注入
轉自:http://blog.csdn.net/u011579138/article/details/51379066 注入簡介 Spring注入可以理解為是對一個物件進行初始化,也就是省去new的這個步驟,類似於工廠模式一樣,通過一個工廠製造出這個物件,如果遇到修
Spring的類屬性註解注入
一.配置applicationContext.xml <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans"
7、SSM框架-Spring之IOC的註解注入(7)
用註解來向Spring容器註冊Bean。需要在applicationContext.xml中註冊<context:component-scan base-package=”pagkage1[,pagkage2,…,pagkageN]”/>。 如:在base-pa
(轉)java之Spring(IOC)註解裝配Bean詳解
pos work 多個 public pre tor not 註解裝配 creat 在這裏我們要詳細說明一下利用Annotation-註解來裝配Bean。 因為如果你學會了註解,你就再也不願意去手動配置xml文件了,下面就看看Annotation的魅力所在吧。 先
【Spring三】使用註解配置bean
原理: 1、當啟動spring容器的時候,給spring容器的bean建立物件 2、當spring容器解析到<context:annotation-config></context:annotation-config>的時候, spring容器掃描
SQL注入及防止注入措施
1、Sql注入是怎麼產生的? WEB開發人員無法保證所有的輸入都已經過濾 攻擊者利用傳送給SQL伺服器的輸入資料構造可執行的SQL程式碼 資料庫未做相應的安全配置 2、如何尋找Sql注入? 識別web應用中的所有輸入點 瞭解哪些型別的請求會出發異
Spring Boot配置及註解詳解
一般情況下,我們建立了一個Spring Boot程式之後,按照預設的配置就可以啟動了,但是我們還是可以自定義一些配置以及修改一些配置一:多個環境的檔案配置由於一個專案在開發的過程當中,需要經歷開發測試以及正式部署三個階段,我們可以根據不同的環境作不同的配置,配置的格式嚴格遵循
Spring依賴注入及使用註解注入bean
Spring 最認同的技術是控制反轉的依賴注入(DI)模式。控制反轉(IoC)是一個通用的概念,它可以用許多不同的方式去表達,依賴注入僅僅是控制反轉的一個具體的例子。 IOC : Inverse Of Control 控制反轉 作用:建立物件 並且維護物件之間的
Spring 使用註解完成bean例項化、依賴注入的相關配置以及注意事項
一、 相關配置例項化註解介紹 首先使用註解完成spring容器例項的配置,主要用到以下幾個: 1、@Repository(“name”):配置持久層例項bean,通常用在DAO; 這裡配置的name屬性相當於在 2、@Servic
Spring 註解實現Bean依賴注入之@Qualifier
三、@Qualifier:限定描述符,用於細粒度選擇候選者; @Autowired預設是根據型別進行注入的,因此如果有多個型別一樣的Bean候選者,則需要限定其中一個候選者,否則將丟擲異常 @Qualifier限定描述符除了能根據名字進行注入,更能進行更細粒度的控制如何選擇
Spring 註解實現Bean依賴注入之@Required
對應於基於XML配置中的依賴檢查,但XML配置的依賴檢查將檢查所有setter方法; 基於@Required的依賴檢查表示註解的setter方法必須,即必須通過在XML配置中配置setter注入,如果沒有配置,在容器啟動時會丟擲異常,從而保證在執行時不會遇到空指標異常,@Required只能放置在set
Spring中註解注入bean和配置檔案注入bean
註解的方式確實比手動寫xml檔案注入要方便快捷很多,省去了很多不必要的時間去寫xml檔案 按以往要注入bean的時候,需要去配置一個xml,當然也可以直接掃描包體,用xml注入bean有以下方法: 1 <?xml version="1.0" encoding="UTF-8"?> 2
spring 使用註解注入bean
學了兩種使用註解注入bean的方式,按照網上提供的方法學習並整理的。 1、@Resource 2、@Autowired 首先要說明的是 spring的標頭檔案,下面是一個比較全的標頭檔案 <beans xmlns="http://www.springfram
Spring依賴注入(構造引數注入、集合,陣列屬性注入、XML自動注入 ,全註解配置)
依賴注入 構造引數注入 --> 常用的是方案一和方案二 MyBean類 YouBean類 <?xml version="1.0" encodin
spring的依賴注入 -------基於註解方式
前言: 做了2年的軟體,剛開始入行的時候,沒有個目標基本上都是在摸索,技術看的我眼花繚亂,這個想學,那個也想學結果是對很多技術一知半解的,工作中才發現,我們要掌握的一門可以搞定快速開發搞定所有業務需求的技術, 所以現在我要對spring的東西達到一個深層次的掌握,儘量避免百度,在開發
spring boot去除掃描自動注入依賴方法——Spring常用註解使用方法
問題: 最近做專案的時候,需要引入其他的jar。然後還需要掃描這些jar裡的某些bean。於 是使用註解:@ComponentScan 這個註解直接指定包名就可以,它會去掃描這個包下所有的class,然後判斷是否解析: 原始碼: public @interface SpringBoo
spring依賴注入: 註解注入
註解注入顧名思義就是通過註解來實現注入, Spring和注入相關的常見註解有Autowired、Resource、Qualifier、Service、Controller、Repository、Component。 [email protected]是自動注入
Spring 在靜態工具類中使用註解注入bean
問題 最近在專案中遇到這樣一個情況:有一個傳送郵件的工具類。在這個工具類中提供了幾種靜態方法,靜態方法需要另外一個類的例項提供處理。在static方法裡呼叫注入進來的service,因為是靜態方法,所以必須宣告該service也必須是static的,這時候發現
spring 框架中的依賴注入(IOC--設值注入)--使用註解--的具體例項的簡單實現
體現了具體專案工程裡面的分層,dao,daoImpl,service,serviceImpl,action。讓你真正的理解這為啥分層。 順便清清楚楚的理解@Component、@Service、@Re
spring 在單例類中使用註解注入bean
/** * @author: jerry * @Email: * @Company: * @Action: 日誌處理工具類 * @DATE: 2016-9-19 */ @Component//泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註 p