SpringMVC實現依賴注入的幾個常用註解的用法解釋和示例說明
在以前,我們使用Spring對一些屬性進行依賴注入(DI)時,通常都是通過在配置檔案中配置一個個的<bean>標籤來實現,比如說這樣:
<bean id="userBiz" class="cn.zifangsky.biz.UserBizImpl"> <property name="userDAO" ref="userDAO"/> </bean>
但是一旦專案大了之後,如果要把所有的這些依賴關係都在配置檔案中配置的話,無疑邏輯上是非常混亂的,這時我們就可以考慮使用幾個常用的註解來實現依賴關係的注入。
實現依賴注入的幾個常用註解分別是:
-
@Component 是所有受Spring 管理元件的通用形式,但是不推薦使用
-
@Repository 對應資料訪問層的Bean
-
@Service 對應業務層的Bean
-
@Controller 對應控制層的Bean
除了這幾個對類的註解外,還有幾個對類中屬性的註解,主要目的是告訴Spring這個屬性應該用那個前面已經註解過的類來例項化,它們分別是:
-
@Resource 預設按名稱來裝配注入,只有當找不到與名稱相匹配的bean時才會按照型別來裝配注入
-
@Autowired 預設按型別來裝配注入,如果想按照名稱來裝配注入,則需要結合@Qualifier一起使用
-
@Qualifier 預設按名稱來裝配注入
由於@Autowired是按照型別來注入的,因此當同類型的變數有多個需要注入時,僅僅使用@Autowired就會出現問題,這時可以結合@Qualifier來使用,比如:
@Autowired @Qualifier("userDaoImpl") private UserDao userDao;
當然,由於@Resource這個註解有另外兩個註解都有的功能,同時@Resource這個註解是基於J2EE的,而@Autowired和@Qualifier是屬於Spring的,所以我們最好使用@Resource進行依賴注入,有利於減小應用與Spring的耦合
對於上面提到的這些註解的一些具體用法,接下來我將以一個具體的例項來舉例說明:
一 測試環境的搭建
1 專案結構與相關jar包:
2 web.xml以及springmvc-servlet.xml:
i)web.xml:
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" version="3.1"> <servlet> <servlet-name>springmvc</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springmvc</servlet-name> <url-pattern>*.html</url-pattern> </servlet-mapping> <filter> <filter-name>characterEncodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>characterEncodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> </web-app>
ii)springmvc-servlet.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" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd"> <context:component-scan base-package="cn.zifangsky.dao" /> <context:component-scan base-package="cn.zifangsky.service" /> <context:component-scan base-package="cn.zifangsky.controller" /> <!-- <context:component-scan base-package="cn.zifangsky.* *.controller" /> --> <context:annotation-config /> <!-- 啟用Bean中定義的註解 --> <mvc:annotation-driven /> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/pages/" /> <property name="suffix" value=".jsp" /> </bean> </beans>
可以看出,在上面的配置檔案中定義了三個“context:component-scan”標籤分別用於掃描資料訪問層、業務層以及控制層的註解,其他配置不用多說
二 註解的使用例項
1 首先是model層的User.java:
package cn.zifangsky.model; public class User { private String name; private String password; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
這一層只是簡單定義了一個“User”模型,並沒有使用到任何註解
2 資料訪問層的UserDao.java和UserDaoImpl.java:
i)UserDao.java:
package cn.zifangsky.dao; import cn.zifangsky.model.User; public interface UserDao { /** * 校驗登入資訊 * */ public String check(User u); }
ii)UserDaoImpl.java:
package cn.zifangsky.dao.impl; import org.springframework.stereotype.Repository; import cn.zifangsky.dao.UserDao; import cn.zifangsky.model.User; @Repository("userDaoImpl") public class UserDaoImpl implements UserDao { public String check(User u) { //這裡只是簡單判斷是否為空,實際需要查詢資料庫等操作 if(u != null){ System.out.println("登入的使用者資訊是:"); System.out.println("--|使用者名稱:" + u.getName()); System.out.println("--|密碼:" + u.getPassword()); } return "ok"; } }
可以看出,在上面的程式碼中我們在類上定義了一個@Repository註解,用於表示這個類是資料訪問層的,同時給它起了個名字叫“userDaoImpl”。問:為什麼在實現類上新增@Repository註解而不是在UserDao介面上添加註解?
其實這個問題只要想一下我們在配置檔案中使用<bean>標籤是如何配置的就清楚了,比如對於這樣一個bean:
<bean id="userDAO" class="cn.zifangsky.dao.UserDAOImpl"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
我們可以發現,“class”屬性這裡指向的是一個具體的實現類而不是它的介面。原因很簡單,我們需要的是一個具體的類來例項化或者說在其他類中也需要這樣一個具體的類來進行引數注入,顯然這是不能使用介面的。因此,上面為何在一個實現類上添加註解也是基於同樣的道理,不信可以試試把@Repository註解從UserDaoImpl轉移到UserDao這個介面上,看看專案執行時會不會報錯?
3 業務邏輯層UserService.java和UserServiceImpl.java:
i)UserService.java:
package cn.zifangsky.service; import cn.zifangsky.model.User; public interface UserService { /** * 模擬登入 * */ public String login(User u); }
ii)UserServiceImpl.java:
package cn.zifangsky.service.impl; import javax.annotation.Resource; import org.springframework.stereotype.Service; import cn.zifangsky.dao.UserDao; import cn.zifangsky.model.User; import cn.zifangsky.service.UserService; @Service("userServiceImpl") public class UserServiceImpl implements UserService { @Resource(name = "userDaoImpl") private UserDao userDao; // public void setUserDao(UserDao userDao) { // this.userDao = userDao; // } public String login(User u) { return userDao.check(u); } }
在這裡,UserServiceImpl這個類上面定義了一個@Service註解,表示它是業務邏輯層上的一個類,同樣給它起了一個名字叫“userServiceImpl”。通過上面的程式碼可以看到,我們給userDao這個屬性定義了一個@Resource註解,通過一個“name”屬性表示引用的是一個名為“userDaoImpl”的UserDao型別的類來例項化userDao屬性,毫無疑問這裡指的就是上面定義了“@Repository(“userDaoImpl”)”註解的UserDaoImpl.java了
注:給屬性添加了註解之後是可以不用再寫對應的setter方法的
4 控制層UserController.java:
package cn.zifangsky.controller; import javax.annotation.Resource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import cn.zifangsky.model.User; import cn.zifangsky.service.UserService; @Controller public class UserController { @Resource(name="userServiceImpl") private UserService userService; @RequestMapping(value="/analogLogin") public String user(@RequestParam(name="name",required=false) String name,@RequestParam(name="password",required=false) String password){ User user = new User(); user.setName(name); user.setPassword(password); String result = userService.login(user); System.out.println(result); return "success"; } }
@Controller註解的含義這裡就不用多說了,跟上面的@Repository和@Service類似。通過定義的@RequestMapping註解我們在訪問“http://localhost:[port]/AnnotationDemo/analogLogin.html”就可以轉到user這個方法進行處理。而@RequestParam註解則是用來獲取請求中的引數用的
三 測試
在瀏覽器中訪問:http://localhost:8090/AnnotationDemo/analogLogin.html?name=haha&password=123qwe
對應的輸出如下:
登入的使用者資訊是: --|使用者名稱:haha --|密碼:123qwe ok
如果出現上面的控制檯輸出則表明註解已經配置正確了
相關推薦
SpringMVC實現依賴注入的幾個常用註解的用法解釋和示例說明
在以前,我們使用Spring對一些屬性進行依賴注入(DI)時,通常都是通過在配置檔案中配置一個個的<bean>標籤來實現,比如說這樣: <bean id="userBiz" class="cn.zifangsky.biz.UserBizImpl">
SpringMVC中幾個常用註解的用法
一、@Controller 以前在編寫Controller方法的時候,需要開發者自定義一個Controller類實現Controller介面,實現handleRequest方法返回ModelAndView。並且需要在Spring配置檔案中配置Handle,將
J2EE中幾個常用的名詞解釋
container ica 一致性 框架 管理 cor 兼容性 系統 自己 1.web容器:給處於其中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接和容器中的環境變量接接口互,不必關註其它系統問題。主要有WEB服務器來實現。例如:T
幾個常用術語名詞解釋 MSISDN,MSRN…
MSRN:Mobile Station Roaming Number,中文即:移動臺漫遊號 這是針對移動臺的移動特性所使用的號碼。每次呼叫發生時,HLR知道目前使用者處在哪一個MSC/VLR服務區內,為了向GMSC提供一個本次路由選擇的臨時號碼,HLR請當前的MSC/VLR分配一個移動臺漫遊號碼
springmvc的五個常用註解?
1、@Controller 在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在Spring
客觀面試題--32.說下springmvc的五個常用註解?
1、@Controller在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把使用者請求的資料經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在SpringMV
JS實現迴圈給元素繫結事件的幾個常用方法
作為一個JS的初學者,想對一些元素迴圈繫結事件的時候總是出現各種問題,尤其是在對閉包沒有熟練掌握的時候更是一頭霧水。網上一查,果然好多初學者有這個困惑,既然這個問題總是出現,於是在我就總結了以下兩個比較好理解的解決方案,分享給大家:(可能還有更好的方式我沒有發現,請各位前輩
【Annotation】使用自定義註解實現依賴注入
import java.util.Map; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.HashMap; /** * 演示類 * @author student */ public
PHP執行系統命令的有幾個常用的函數
exe 自動 文件操作 nal 外部命令 中間 ring 打開 lcm PHP執行系統命令的有幾個常用的函數,如有:system函數、exec函數、popen函數,passthru,shell_exec函數他們都可以執行系統命令,不過前提時必須系統給了權限了哦。 syste
miniui幾個常用知識點匯總
簡單 去除 spa 自帶 超過 表格 繪制 val wro 1.在表格中去除系統自帶的序列號,請看代碼: function allAndBrief(id) { if(id==1){ grid.set({
hadoop的幾個常用命令
hadoop官方文檔:http://hadoop.apache.org/docs/r1.2.1/file_system_shell.html1、登錄主節點,切換到hdfs用戶[[email protected]/* */~]#su - hdfs2、列出當前目錄有哪些子目錄,有哪些文件[[email
封裝對象,包含幾個常用方法
nts opp 操作 阻止事件冒泡 3.1 坐標 stop pre 處理 這兩天復習了DOM事件綁定,記錄一下,便於復習學習。 1 事件處理程序 1.1 HTML事件處理程序:直接寫在html中,和html不解耦,修改麻煩 1.2 DOM0級事件處理程序:不寫在html
Python:print()函數的幾個常用參數
com file open 默認 strong 其他 end 空格 文件的 1.參數sep:設置輸出字符產之間的字符串。默認是空格 1 name=‘Tomwenxing‘ 2 age=‘23‘ 3 job=‘student‘ 4 print(name,age,job) 5
請求網頁幾個常用庫的用法:
完成 data report 第三方庫 () .get 參數說明 進度 函數 1、urllib urlopen()方法urllib.urlopen(url[, data[, proxies]]) :創建一個表示遠程url的類文件對象,然後像本地文件一樣操作這個類文件對
幾個常用網絡/服務器監控開源軟件
memcached 托管 不能 不足 div ios系統 正在 linux下 tle 想要更清晰的了解你的網絡嗎?沒有比這幾個免費的工具更好用的了。 網絡和系統監控是一個很寬的範疇。有監控服務器、網絡設備、應用正常工作的方案,也有跟蹤這些系統和設備性能,提供趨勢性能分
Python的幾個常用模塊
comm line 時間 sdi make 常用模塊 常用 一級目錄 就會 一、sys 用於提供對Python解釋器相關的操作: sys.argv 命令行參數List,第一個元素是程序本身路徑 sys.exit(n) 退出程序,正常退
幾個常用規則引擎的簡單介紹和演示
規則引擎 drools ilog odm Ilog JRules 是最有名的商用BRMS;Drools 是最活躍的開源規則引擎;Jess 是Clips的java實現,就如JRuby之於Ruby,是AI系的代表;Visual Rules(旗正規則引擎)國內商業規則引擎品牌。今天對比了一下這四個頗
js 實現每隔幾個字符進行添加字符串
實現 regexp reverse false turn bsp ret var reg function Xreplace(str,length,reversed) { var re = new RegExp("\\d{1,"+length+"}","g");
Eclipse的幾個常用快捷鍵
單行 處理 所在 格式化 個常用快捷鍵 變量名 pan 單行註釋 自己 鍵盤操作 功能 Alt + / 語句或變量名自動補全 Ctrl + Shift + F 語句格式化 Ctrl + /
XPATH的幾個常用函數
寫法 www. ins 如果 情況 true id屬性 text 常用 1.contains (): //div[contains(@id,‘in‘)] ,表示選擇id中包含有’in’的div節點2.text():由於一個節點的文本值不屬於屬性,比如