1. 程式人生 > >SpringMvc註解開發

SpringMvc註解開發

1.四大註解的定義
(1)Controller註解:該註解使用在一個類上面,引數為value,值為訪問該controller的名稱,預設為空,如果為空
則值為該controller類名的首字母小寫的值。程式碼如下:

1 @Documented
2 @Target(ElementType.TYPE)
3 @Inherited
4 @Retention(RetentionPolicy.RUNTIME)
5 public @interface Controller {
6         String value() default "";
7 }    


(2)Service註解:該註解使用在一個類上面(使用在介面的實現類上面),引數為value,值為該service的名稱。預設為空,
如果為空則值為該service的類名的首字母小寫的值。程式碼如下:

1 @Documented
2 @Inherited
3 @Target(ElementType.TYPE)
4 @Retention(RetentionPolicy.RUNTIME)
5 public @interface Service {
6         String value() default "";
7 }    


(3)RequestMapping註解:該註解定義使用在一個方法上面,引數為value,值為該方法的訪問名稱,預設為空,如果
為空,則值為該方法的方法名首字母小寫的值。程式碼如下:

1 @Documented
2 @Inherited
3 @Target(ElementType.METHOD)
4 @Retention(RetentionPolicy.RUNTIME)
5 public @interface RequestMapping {
6     String value() default "";
7 }


(4)Autowired註解:該註解定義使用到類的成員變數上面,沒有引數,表示該變數欄位注入值。程式碼如下:

1 @Documented
2 @Inherited
3 @Target(ElementType.FIELD)
4 @Retention(RetentionPolicy.RUNTIME)
5 public @interface Autowired { 6 7 }

2.包掃描方法說明
當我們獲取到一個指定的包名時,我們要去獲取該包路徑下面的所有檔案,如果該檔案為資料夾,在遞迴呼叫該方法,直到
獲取到指定包路徑下面的所有檔案,判讀檔案是否以class結尾,如果檔案以class結尾,則將該檔案的完整路徑(包名+檔名)
儲存到list中。
(1)先將包名中的所以有"."替換為"/",得到包的路徑。

1 private String replacePackageName(String packageName){
2     return packageName.replaceAll("\\.", "/");
3 }


(2)遞迴呼叫掃描方法,獲取所有檔案。

 1 private void scanPackage(String packageName){
 2         //替換包名中的 .
 3         String packageName1 = replacePackageName(packageName);
 4         //獲取當前的統一資源定位符
 5         URL url = this.getClass().getClassLoader().getResource(packageName1);    
 6         //獲取此URL的檔名
 7         String pathFile= url.getFile();
 8         //通過將給定路徑名字串轉換成抽象路徑名來建立一個新 File 例項
 9         File file = new File(pathFile);
10         //返回由此抽象路徑名所表示的目錄中的檔案和目錄的名稱所組成字串陣列。
11         String[] files = file.list();
12         for(String filePath : files){
13             //根據目錄名稱和檔名稱建立新的File物件
14             File eachFile = new File(pathFile+"/"+filePath);
15             if(eachFile.isDirectory()){
16                 //如果為資料夾,則將新的名稱作為包名,再次呼叫該方法。
17                 scanPackage(packageName+"."+eachFile.getName());
18             }else{
19                 //判斷檔案的副檔名是否為class,如果是,則將該檔案的包名和檔名一起儲存到集合中。
20                 if(getFileExtendName(eachFile.getName()).equals("class"))
21                     packageNames.add(packageName+"."+eachFile.getName());
22                 continue;
23             }
24         }
25     }

 1 private String getFileExtendName(String fileName){
 2         //判斷傳入的檔名是否為空,或者長度是否小於等於0
 3         if(fileName == null ||fileName.length() <=0)
 4             return null;
 5         //獲取檔案中最後一個 . 出現的地方的下標
 6         int lastIndex = fileName.lastIndexOf(".");
 7         //判斷下標是否為正常的值
 8         if(lastIndex > -1 && lastIndex <(fileName.length()-1))
 9             //擷取檔案的副檔名
10             return fileName.substring(lastIndex+1);
11         return fileName;
12     }


3.例項化第二步掃描到的所有類中配有controller和service註解的類

 1 private void saveClass() throws Exception{
 2         //判斷集合是否為空
 3         if(packageNames.size() <=0){
 4             return;
 5         }
 6         for(String pkn:packageNames){
 7             //根據類的全限定名通過反射獲取指定類的class物件
 8             Class<?> object = Class.forName(pkn.replace(".class", "").trim());
 9             //判斷該類是否有controller註解
10             if(object.isAnnotationPresent(Controller.class)){
11                 //例項化該class的類物件
12                 Object instance = object.newInstance();
13                 //獲取controller註解的物件
14                 Controller controller = object.getAnnotation(Controller.class);
15                 //獲取該註解的引數的值
16                 String key = controller.value();
17                 //判斷註解的值是否為空
18                 if(key.equals("")){
19                     //獲取該類的類名首字母小寫作為值。
20                     key=object.getSimpleName().substring(0, 1).toLowerCase()+object.getSimpleName().substring(1);
21                 }
22                 //將類的名稱和類的例項放到map物件中
23                 classMap.put(key, instance);
24                 //判斷該物件是否有service註解
25             }else if(object.isAnnotationPresent(Service.class)){
26                 //獲取該類的例項
27                 Object instance = object.newInstance();
28                 //獲取service的物件例項
29                 Service service = object.getAnnotation(Service.class);
30                 //獲取註解的值
31                 String key = service.value();
32                 //判斷註解的值是否為空
33                 if(key.equals("")){
34                     //獲取該類的類名首字母小寫作為值。
35                     key=object.getSimpleName().substring(0, 1).toLowerCase()+object.getSimpleName().substring(1);
36                 }
37                 //將類的名稱和類的例項放到map物件中
38                 classMap.put(key, instance);
39             }else{
40                 continue;
41             }
42         }        
43     }


4.根據所有的類物件獲取方法

 1 private void handlerMap(){
 2         //判斷類的集合是否為空
 3         if(classMap.size() <=0){
 4             return;
 5         }
 6         //遍歷該map物件
 7         for (Map.Entry<String,Object> entry : classMap.entrySet()) {
 8             //獲取該類是否有controller註解
 9             if(entry.getValue().getClass().isAnnotationPresent(Controller.class)){
10                 //獲取controller註解物件
11                 Controller controller = entry.getValue().getClass().getAnnotation(Controller.class);
12                 //獲取controller註解的值
13                 String value = controller.value();
14                 //判斷註解的值是否為空
15                 if(value.equals("")){
16                     //獲取該類的類名首字母小寫作為值。
17                     value=entry.getValue().getClass().getSimpleName().substring(0, 1).toLowerCase()+entry.getValue().getClass().getSimpleName().substring(1);
18                 }
19                 //反射獲取該類下面的所有方法
20                 Method[] methods = entry.getValue().getClass().getMethods();
21                 for (Method method : methods) {
22                     //判斷該方法是否有RequestMapping註解
23                     if(method.isAnnotationPresent(RequestMapping.class)){
24                         //獲取RequestMapping物件
25                         RequestMapping requestMapping = method.getAnnotation(RequestMapping.class);
26                         //獲取註解的值
27                         String rvalue = requestMapping.value();
28                         //判斷註解的值是否為空
29                         if(rvalue.equals("")){
30                             //獲取該類的類名首字母小寫作為值。
31                             rvalue=method.getClass().getSimpleName().substring(0, 1).toLowerCase()+method.getClass().getSimpleName().substring(1);
32                         }
33                         //將controller的名稱和方法的名稱儲存到集合中
34                         methodMap.put("/"+value+rvalue, method);
35                     }else{
36                         continue;
37                     }
38                 }
39             }else{
40                 continue;
41             }
42         }
43     }


5.例項化類中的有Autowired註解的成員變數

 1 private void ioc(){
 2         //判斷集合是否為空
 3         if(classMap.size() <=0){
 4             return;
 5         }
 6         //變數所有的類
 7         for (Map.Entry<String, Object> entry : classMap.entrySet()) {
 8             //獲取本類下面所有的成員變數
 9             Field[] fileds =entry.getValue().getClass().getDeclaredFields();
10             for (Field field : fileds) {
11                 //設定該成員變數可以編輯
12                 field.setAccessible(true);
13                 //判斷該成員物件是否有Autowired註解
14                 if(field.isAnnotationPresent(Autowired.class)){
15                     try {
16                         //設定該成員變數可以編輯
17                         field.setAccessible(true);
18                         //獲取包名
19                         String packString= field.getType().getPackage().getName();
20                         //獲取實現類的類名
21                         String className=  field.getType().getSimpleName()+"Impl";
22                         //反射該類物件
23                         Class<?> obj = Class.forName(packString+".impl."+className);
24                         String value="";
25                         //判斷該類是否有controller註解
26                         if(obj.isAnnotationPresent(Controller.class)){
27                             //獲取controller的值
28                             value= obj.getAnnotation(Controller.class).value();
29                             if(value.equals("")){
30                                 //獲取該類的類名首字母小寫作為值。
31                                 value=obj.getSimpleName().substring(0, 1).toLowerCase()+obj.getSimpleName().substring(1);
32                             }
33                         //判斷該類是否有service註解
34                         }else if(obj.isAnnotationPresent(Service.class)){
35                             //獲取service的值
36                             value= obj.getAnnotation(Service.class).value();
37                             if(value.equals("")){
38                                 //獲取該類的類名首字母小寫作為值。
39                                 value=obj.getSimpleName().substring(0, 1).toLowerCase()+obj.getSimpleName().substring(1);
40                             }
41                         }
42                         //給成員變數賦值例項
43                         field.set(entry.getValue(), classMap.get(value));
44                     } catch (IllegalArgumentException | IllegalAccessException | ClassNotFoundException e) {
45                         e.printStackTrace();
46                     }
47                 }
48             }
49         }
50     }


6.寫前端控制器
前端控制器是一個servlet,所有的路徑訪問都提交到該servlet,由該servlet負責轉發。在該servlet的初始化init方法中執行上面步驟。
然後在post方法中攔截請求。獲取地址,進行轉發。

 1 private void ioc(){
 2         //判斷集合是否為空
 3         if(classMap.size() <=0){
 4             return;
 5         }
 6         //變數所有的類
 7         for (Map.Entry<String, Object> entry : classMap.entrySet()) {
 8             //獲取本類下面所有的成員變數
 9             Field[] fileds =entry.getValue().getClass().getDeclaredFields();
10             for (Field field : fileds) {
11                 //設定該成員變數可以編輯
12                 field.setAccessible(true);
13                 //判斷該成員物件是否有Autowired註解
14                 if(field.isAnnotationPresent(Autowired.class)){
15                     try {
16                         //設定該成員變數可以編輯
17                         field.setAccessible(true);
18                         //獲取包名
19                         String packString= field.getType().getPackage().getName();
20                         //獲取實現類的類名
21                         String className=  field.getType().getSimpleName()+"Impl";
22                         //反射該類物件
23                         Class<?> obj = Class.forName(packString+".impl."+className);
24                         String value="";
25                         //判斷該類是否有controller註解
26                         if(obj.isAnnotationPresent(Controller.class)){
27                             //獲取controller的值
28                             value= obj.getAnnotation(Controller.class).value();
29                             if(value.equals("")){
30                                 //獲取該類的類名首字母小寫作為值。
31                                 value=obj.getSimpleName().substring(0, 1).toLowerCase()+obj.getSimpleName().substring(1);
32                             }
33                         //判斷該類是否有service註解
34                         }else if(obj.isAnnotationPresent(Service.class)){
35                             //獲取service的值
36                             value= obj.getAnnotation(Service.class).value();
37                             if(value.equals("")){
38                                 //獲取該類的類名首字母小寫作為值。
39                                 value=obj.getSimpleName().substring(0, 1).toLowerCase()+obj.getSimpleName().substring(1);
40                             }
41                         }
42                         //給成員變數賦值例項
43                         field.set(entry.getValue(), classMap.get(value));
44                     } catch (IllegalArgumentException | IllegalAccessException | ClassNotFoundException e) {
45                         e.printStackTrace();
46                     }
47                 }
48             }
49         }
50     }
51

7.配置web.xml檔案

 1 <servlet>
 2           <servlet-name>dispatcherServlet</servlet-name>
 3           <servlet-class>com.jack.servlet.DispatcherServlet</servlet-class>
 4           <init-param>
 5               <param-name>configxml</param-name>
 6               <param-value>com/jack/test/minimvc.xml</param-value>
 7           </init-param>
 8           <load-on-startup>0</load-on-startup>
 9   </servlet>
10   <servlet-mapping>
11           <servlet-name>dispatcherServlet</servlet-name>
12           <url-pattern>/</url-pattern>
13   </servlet-mapping>

相關推薦

springmvc學習筆記(13)-springmvc註解開發之集合類型參數綁定

return 可擴展性 list .net items trac class javascrip lin springmvc學習筆記(13)-springmvc註解開發之集合類型參數綁定

springmvc 註解開發之 validation校驗

專案中使用較多的是前端的校驗,比如頁面中js校驗。對於安全要求較高的建議在服務端進行校驗。 服務端校驗:   控制層controller:校驗頁面請求的引數的合法性,在服務端控制層controller校驗,不區分客戶端型別(瀏覽器、手機客戶端、遠端呼叫)  業務層se

SpringMVC 註解開發

先在一個包中建立一個類,然後再配置sprringmvacontroller.xml並連結到該類。 <context:component-scan base-package="cn.happy.controllerreturn"></context:com

SpringMvc註解開發

1.四大註解的定義 (1)Controller註解:該註解使用在一個類上面,引數為value,值為訪問該controller的名稱,預設為空,如果為空 則值為該controller類名的首字母小寫的值。程式碼如下: 1 @Documented 2 @Targ

SpringMVC註解開發(基礎)---SpringMVC學習筆記(七)

需求 商品修改功能開發。 操作流程: 1、進入商品查詢列表頁面 2、點選修改,進入商品修改頁面,頁面中顯示了要修改的商品(從資料庫查詢) 要修改的商品從資料庫查詢,根據商品id(主鍵)查詢商品資訊 3、在商品修改頁面,修改商品資訊,修改後,點

springmvc(十六)springmvc註解開發-springmvc引數繫結-map繫結

也通過在包裝pojo中定義map型別屬性。 在包裝類中定義Map物件,並新增get/set方法,action使用包裝物件接收。 包裝類中定義Map物件如下: Public class QueryVo

springmvc註解開發-資料回顯

資料回顯 什麼是資料回顯 提交後,如果出現錯誤,將剛才提交的資訊回顯到剛才提交介面 pojo資料回顯方法 1、springmvc預設對pojo的資料進行回顯。       pojo資料傳入Cont

springmvc 註解開發 處理器方法的返回值

pri ajax mvc img 返回值 -1 分享 alt spring 1.返回void -Ajax請求 後臺: 前臺: springmvc 註解式開發 處理器方法的返回值

SpringMVC 學習 十 SSM環境搭建(三)springMVC檔案配置 springMVC學習三 註解開發環境搭建

SpringMVC檔案配置的詳細過程,可以檢視springMVC環境搭建的註解配置篇《springMVC學習三 註解開發環境搭建》 <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://www.w3.org/2

SpringMVC框架(1)之(1.3 註解開發&Controller方法返回值)

一、 註解開發基礎: 1. @RequestMapping 註解(在Controller類上或方法上,用於指定 url和請求方式): 1. 設定方法對應的URL(一個方法對應一個URL); 2. 設定請求的根路徑;(eg:http:// localhost:8080/project/bo

Java框架(十四)之springMVC註解開發

一、註解入門 1.配置springMVC配置檔案 <!-- 添加註解掃描 --> <context:component-scan base-package="com.qf"></context:component-scan>

springmvc註解開發

搭建環境 後端控制器無需實現介面,新增相應的註解 springmvc配置檔案中無需註冊controller springmvc配置檔案中新增元件掃描器、註解驅動 涉及常用的註解 @controller、@RequestMapping(類體上【名稱空間】、方法上)起到限定範圍的作用 @

SpringMVC (二)非註解開發註解開發

非註解的對映器 所有的對映器都實現了HandlerMapping介面。 原始的對映器:org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping Handler:<bean name="/quer

SpringMVC註解開發

案例 3.2 path view username component date property xsd ---恢復內容開始--- 1.SpringMVC註解開發的案例 配置DispatchServlet-Servlet.xml文件 <?xml versi

SpringMVC 註解

哪些 轉存 .class spring 屬性 選擇 允許 model mvc 1.@SessionAttributes 允許我們有選擇地指定Model中的哪些屬性需要轉存到HttpSession中對象中 只能聲明在類上,而不能聲明在方法上 @SessionAt

spring IOC快速入門,屬性註入,註解開發

復雜 void erl main http val rri prop turn 我們使用spring框架也會使用到配置文件,我們需要在src下創建一個關於spring的配置文件,一般情況名稱叫applicationContext.xml 基本約束: <!DOCT

JAVAEE——SSH項目實戰06:統計信息管理、Spring註解開發和EasyUI

disabled path -a ted efault pen ret 發送 tran 作者: kent鵬 轉載請註明出處: http://www.cnblogs.com/xieyupeng/p/7190925.html 一、統計信息管理    二、Spring

/----------關鍵字:springmvc註解

.cn 技術 多個 ng- 分享 創建 adapt handler welcome M1:這篇內容是在上一篇的基礎上進行的修改。具體步驟如下: M2:新建項目Dynamic Web Project 項目annotation M3:其它地方不變只需要對springmvc_

mybatis註解開發,動態sql

sele sel myba 開始 xls inorder from all nbsp 在利用mybatis註解開始時,如果沒有用到動態sql時,可以直接寫 @Select("select * from order") List<XlSubOrder> getA

Spring基於註解開發異常

lib con 版本 mil line tex 宋體 開發 style 基於註解開發: 一開始:用的jar包: 百度查到: 導入aop包: 沒用 有的說: Spring版本和jdk版本不匹配 於是我換成了4.0版本 導入的jar包: