spring-boot注解詳解(四)

@repository

@repository跟@Service,@Compent,@Controller這4種注解是沒什么本質區別,都是聲明作用,取不同的名字只是為了更好區分各自的功能.下圖更多的作用是mapper注冊到類似于以前mybatis.xml中的mappers里.
在這里插入圖片描述
也是因為接口沒辦法在spring.xml中用bean的方式來配置實現類吧(接口配不了),所以只能用注解或者mybatis.xml中掃描bean的方式來生成實現類吧
一,首先:@repository是用來注解接口,如下圖:這個注解是將接口BookMapper的一個實現類(具體這個實現類的name叫什么,還需要再分析源碼找找看)交給spring管理(在spring中有開啟對@repository注解的掃描),當哪些地方需要用到這個實現類作為依賴時,就可以注入了.當然我們也可以主動給這個實現類命名,如下圖

在這里插入圖片描述
二,為什么有時候我們不用@repository來注解接口,我們照樣可以注入到這個接口的實現類呢?如下圖,下圖是在接口沒有用

@repository注解的情況下,依然可以實現注入它的實現類.
在這里插入圖片描述
上面是在idea中報了紅線警告,說找不到這個實現類,但依然是可以運行,沒有問題(只是單純的警告),而在myeclipse中,是連警告都沒有的,運行完全沒問題.這是因為如下圖:
在這里插入圖片描述
是因為我們在mybatis的xml文件配置了上圖這個bean,它會去將dao這個層中的mapper(也就是我們的接口)都生成實現類,然后交給spring管理(因為mybatis.xml文件我們最終還是導入了spring容器中),所以我們這里不對這些接口用@repository注解,也是一樣可以用它的實現類,(這也是我們寫項目時,有時感覺完全是沒用到@repository注解的原因,因為沒有什么必要)而idea報紅線警告,可能是idea自己的原因,這個在我們對它對應的接口用@repository注解后,紅線警告會消失,運行也完全沒問題

@RequestBody:

作用:

主要用來接收前端傳遞給后端的json字符串中的數據的(請求體中的數據的);
要求:

GET方式無請求體,所以使用@RequestBody接收數據時,前端不能使用GET方式提交數據,而是用POST方式進行提交。

在后端的同一個接收方法里,@RequestBody與@RequestParam()可以同時使用,@RequestBody最多只能有一個,而@RequestParam()可以有多個。

簡言之:

一個請求——》只有一個@RequestBody;

一個請求——》可以有多個@RequestParam。
******①同時使用@RequestParam()和@RequestBody

@RequestParam( )指定的參數可以是普通元素、數組、集合、對象等等

 (即: @RequestBody 與@RequestParam()可以同時使用時,原SpringMVC接收參數的機制不變,只不過RequestBody 接收的是請求體里面的數據(get是默認的請求體,post是提交表單需要的請求體);而RequestParam接收的是key-value里面的參數,所以它會被切面進行處理從而可以用普通元素、數組、集合、對象等接收)。

因此:

1、如果參數時放在請求體中,傳入后臺的話,那么后臺要用@RequestBody才能接收到

否則就會在數據庫中不能完成curd操作; 
     在這里插入圖片描述
      2、如果不是放在 請求體中的話,那么后臺接收前臺傳過來的參數時,要用@RequestParam來接收,或則形參前什么也不寫也能接收。

******②參數前寫了@RequestParam(xxx)

   1、前端必須有對應的xxx名字才行(不管是否有值,可通過設置該注解的required屬性來調節是否必須傳)2、如果沒有xxx名的話,那么請求會出錯,報400。

******③參數前不寫@RequestParam(xxx)

1、前端是否有對應的xxx名字都行,如果有xxx名的話,那么就會自動匹配

2、沒有的話,請求也能正確發送。

  &&&追注:這里與feign消費服務時不同;feign消費服務時,如果參數前什么也不寫,那么會被默認@RequestBody的。

******④如果后端參數是一個對象,且該參數前是以@RequestBody修飾的,那么前端傳遞json參數時,必須滿足以下要求:

后端@RequestBody注解對應的類在將HTTP的輸入流(含請求體)裝配到目標類

(也就是:@RequestBody后面的類)時,會根據json字符串中的key來匹配對應實體類的屬性,如果匹配一致且json中的該key對應的值符合)

(或者說:實體類的對應屬性的類型要求時,會調用實體類的setter方法將值賦給該屬性。)

1、json字符串中,如果value為 “” 的話(空串),后端對應屬性如果是String類型的,那么接受到的就是 “”

如果是后端屬性的類型是Integer、Double等類型,那么接收到的就是null。

2、json字符串中,如果value為null的話,后端對應收到的就是null。

3、如果某個參數沒有value的話,在傳json字符串給后端時,要么干脆就不把該字段寫到json字符串中;要么寫value時, 必須有值,null 或""都行。

千萬不能有類似"stature":,這樣的寫法,如:
    在這里插入圖片描述
    總結:

結論①:@JsonAlias注解,實現:json轉模型時,使json中的特定key能轉化為特定的模型屬性;但是模型轉json時,
對應的轉換后的key仍然與屬性名一致

結論②:@JsonProperty注解,實現:json轉模型時,使json中的特定key能轉化為指定的模型屬性;同樣的,模
型轉json時,對應的轉換后的key為指定的key

結論③:@JsonAlias注解需要依賴于setter、getter,而@JsonProperty注解不需要。

結論④:在不考慮上述兩個注解的一般情況下,key與屬性匹配時,默認大小寫敏感。

結論⑤:有多個相同的key的json字符串中,轉換為模型時,會以相同的幾個key中,排在最后的那個key的值給模
型屬性復制,因為setter會覆蓋原來的值。見示例中的gender屬性。

結論⑥:后端@RequestBody注解對應的類在將HTTP的輸入流(含請求體)裝配到目標類(即:@RequestBody后面
的類)時,會根據json字符串中的key來匹配對應實體類的屬性,如果匹配一致且json中的該key對應的值
符合(或可轉換為)實體類的對應屬性的類型要求時,會調用實體類的setter方法將值賦給該屬性。

@ComponentScan

  1. @ComponentScan注解是什么

其實很簡單,@ComponentScan主要就是定義掃描的路徑從中找出標識了需要裝配的類自動裝配到spring的bean容器中

  1. @ComponentScan注解的詳細使用

做過web開發的同學一定都有用過@Controller,@Service,@Repository注解,查看其源碼你會發現,他們中有一個共同的注解@Component,沒錯@ComponentScan注解默認就會裝配標識了@Controller,@Service,@Repository,@Component注解的類到spring容器中,好下面咱們就先來簡單演示一下這個例子

在包com.zhang.controller下新建一個UserController帶@Controller注解如下:

package com.zhang.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
}

在包com.zhang.service下新建一個UserService帶@Service注解如下:

package com.zhang.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {
}

在包com.zhang.dao下新建一個UserDao帶@Repository注解如下:

package com.zhang.dao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
}

新建一個配置類如下:

/*** 主配置類  包掃描com.zhang** @author zhangqh* @date 2018年5月12日*/
@ComponentScan(value="com.zhang")
@Configuration
public class MainScanConfig {
}

新建測試方法如下:

AnnotationConfigApplicationContext applicationContext2 = new AnnotationConfigApplicationContext(MainScanConfig.class);String[] definitionNames = applicationContext2.getBeanDefinitionNames();for (String name : definitionNames) {System.out.println(name);
}

運行結果如下:

mainScanConfig
userController
userDao
userService

怎么樣,包掃描的方式比以前介紹的通過@Bean注解的方式是不是方便很多,這也就是為什么web開發的同學經常使用此方式的原因了

上面只是簡單的介紹了@ComponentScan注解檢測包含指定注解的自動裝配,接下來讓我們來看看@ComponentScan注解的更加詳細的配置,在演示詳細的配置之前,讓我們先看看@ComponentScan的源代碼如下:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {/*** 對應的包掃描路徑 可以是單個路徑,也可以是掃描的路徑數組* @return*/@AliasFor("basePackages")String[] value() default {};/*** 和value一樣是對應的包掃描路徑 可以是單個路徑,也可以是掃描的路徑數組* @return*/@AliasFor("value")String[] basePackages() default {};/*** 指定具體的掃描的類* @return*/Class<?>[] basePackageClasses() default {};/*** 對應的bean名稱的生成器 默認的是BeanNameGenerator* @return*/Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;/*** 處理檢測到的bean的scope范圍*/Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;/*** 是否為檢測到的組件生成代理* Indicates whether proxies should be generated for detected components, which may be* necessary when using scopes in a proxy-style fashion.* <p>The default is defer to the default behavior of the component scanner used to* execute the actual scan.* <p>Note that setting this attribute overrides any value set for {@link #scopeResolver}.* @see ClassPathBeanDefinitionScanner#setScopedProxyMode(ScopedProxyMode)*/ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;/*** 控制符合組件檢測條件的類文件   默認是包掃描下的  **/*.class* @return*/String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;/*** 是否對帶有@Component @Repository @Service @Controller注解的類開啟檢測,默認是開啟的* @return*/boolean useDefaultFilters() default true;/*** 指定某些定義Filter滿足條件的組件 FilterType有5種類型如:*                                  ANNOTATION, 注解類型 默認ASSIGNABLE_TYPE,指定固定類ASPECTJ, ASPECTJ類型REGEX,正則表達式CUSTOM,自定義類型* @return*/Filter[] includeFilters() default {};/*** 排除某些過來器掃描到的類* @return*/Filter[] excludeFilters() default {};/*** 掃描到的類是都開啟懶加載 ,默認是不開啟的* @return*/boolean lazyInit() default false;
}

a,演示basePackageClasses參數,如我們把配置文件改成如下:

@ComponentScan(value="com.zhang.dao",useDefaultFilters=true,basePackageClasses=UserService.class)
@Configuration
public class MainScanConfig {
}

測試結果如下:

mainScanConfig
userDao
userService

b,演示includeFilters參數的使用如下:

在com.zhang.service包下新建一個UserService2類如下:注意沒有帶@Service注解

package com.zhang.service;
public class UserService2 {
}

配置類改成:

@ComponentScan(value="com.zhang",useDefaultFilters=true,includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),@Filter(type=FilterType.ASSIGNABLE_TYPE,classes={UserService2.class})})
@Configuration
public class MainScanConfig {
}

運行結果如下:

mainScanConfig
userController
userDao
userService
userService2

userService2同樣被加入到了spring容器

新增一個自定義的實現了TypeFilter的MyTypeFilter類如下:

/*** 自定義過濾** @author zhangqh* @date 2018年5月12日*/
public class MyTypeFilter implements TypeFilter {public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)throws IOException {AnnotationMetadata annotationMetadata = metadataReader.getAnnotationMetadata();ClassMetadata classMetadata = metadataReader.getClassMetadata();Resource resource = metadataReader.getResource();String className = classMetadata.getClassName();System.out.println("--->"+className);// 檢測名字包含Service的beanif(className.contains("Service")){return true;}return false;}
}

修改主配置如下:

@ComponentScan(value="com.zhang",useDefaultFilters=true,includeFilters={@Filter(type=FilterType.ANNOTATION,classes={Controller.class}),@Filter(type=FilterType.CUSTOM,classes={MyTypeFilter.class})})
@Configuration
public class MainScanConfig {
}

運行結果如下:

mainScanConfig
userController
userDao
userService
userService2

可以發現同樣userService2被加入到了spring容器中

好了includeFilters參數就演示到這,另外一個參數excludeFilters和includeFilters用戶一摸一樣,只是他是過濾出不加入spring容器中,感興趣的同學可以自己試試,我這邊就不演示了

總結一下@ComponentScan的常用方式如下

  • 自定掃描路徑下邊帶有@Controller,@Service,@Repository,@Component注解加入spring容器
  • 通過includeFilters加入掃描路徑下沒有以上注解的類加入spring容器
  • 通過excludeFilters過濾出不用加入spring容器的類
  • 自定義增加了@Component注解的注解方式

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/250156.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/250156.shtml
英文地址,請注明出處:http://en.pswp.cn/news/250156.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

令人叫絕的EXCEL函數功能

http://club.excelhome.net/thread-166725-1-1.html https://wenku.baidu.com/view/db319da0bb0d4a7302768e9951e79b8969026864.html轉載于:https://www.cnblogs.com/cqufengchao/articles/9150401.html

[pytorch、學習] - 4.5 讀取和存儲

參考 4.5 讀取和存儲 到目前為止,我們介紹了如何處理數據以及如何構建、訓練和測試深度學習模型。然而在實際中,我們有時需要把訓練好的模型部署到很多不同的設備。在這種情況下,我們可以把內存中訓練好的模型參數存儲在硬盤上供后續讀取使用。 4.5.1 讀寫tensor 我們可以直…

JAVA排序的方法

//冒泡排序法&#xff1a; package fuxi;public class Bubble { public static void main(String[] args) { int a[] { 10,23,11,56,45,26,59,28,84,79 }; int i,temp; System.out.println("輸出原始數組數據&#xff1a;"); for (i…

spring-boot注解詳解(五)

AutoWired 首先要知道另一個東西&#xff0c;default-autowire&#xff0c;它是在xml文件中進行配置的&#xff0c;可以設置為byName、byType、constructor和autodetect&#xff1b;比如byName&#xff0c;不用顯式的在bean中寫出依賴的對象&#xff0c;它會自動的匹配其它bea…

什么是p12證書?ios p12證書怎么獲取?

.cer是蘋果的默認證書&#xff0c;在xcode開發打包可以使用&#xff0c;如果在lbuilder、phonegap、HBuilder、AppCan、APICloud這些跨平臺開發工具打包&#xff0c;就需要用到p12文件。 .cer證書僅包含公鑰&#xff0c;.p12證書可能既包含公鑰也包含私鑰&#xff0c;這就是他們…

[pytorch、學習] - 4.6 GPU計算

參考 4.6 GPU計算 到目前為止,我們一直使用CPU進行計算。對復雜的神經網絡和大規模數據來說,使用CPU來計算可能不夠高效。 在本節中,將要介紹如何使用單塊NIVIDA GPU進行計算 4.6.1 計算設備 PyTorch可以指定用來存儲和計算的設備,如果用內存的CPU或者顯存的GPU。默認情況下…

adb connect 192.168.1.10 failed to connect to 192.168.1.10:5555

adb connect 192.168.1.10 輸出 failed to connect to 192.168.1.10:5555 關閉安卓端Wi-Fi&#xff0c;重新打開連接即可 轉載于:https://www.cnblogs.com/sea-stream/p/10020995.html

創建oracle數據庫表空間并分配用戶

我們在本地的oracle上或者virtualbox的oracle上 創建新的數據庫表空間操作&#xff1a;通過system賬號來創建并授權/*--創建表空間create tablespace YUJKDATAdatafile c:\yujkdata200.dbf --指定表空間對應的datafile文件的具體的路徑size 100mautoextend onnext 10m*/ /*--創…

spring-boot注解詳解(六)

Target Target說明了Annotation所修飾的對象范圍&#xff1a;Annotation可被用于 packages、types&#xff08;類、接口、枚舉、Annotation類型&#xff09;、類型成員&#xff08;方法、構造方法、成員變量、枚舉值&#xff09;、方法參數和本地變量&#xff08;如循環變量、…

[pytorch、學習] - 5.1 二維卷積層

參考 5.1 二維卷積層 卷積神經網絡(convolutional neural network)是含有卷積層(convolutional layer)的神經網絡。本章介紹的卷積神經網絡均使用最常見的二維卷積層。它有高和寬兩個空間維度,常用來處理圖像數據。本節中,我們將介紹簡單形式的二維卷積層的工作原理。 5.1.1…

[51CTO]給您介紹Windows10各大版本之間區別

給您介紹Windows10各大版本之間區別 隨著win10的不斷普及和推廣&#xff0c;越來越多的朋友想安裝win10系統了&#xff0c;但是很多朋友不知道win10哪個版本好用&#xff0c;為了讓大家能夠更好的選擇win10系統版本&#xff0c;下面小編就來告訴你 http://os.51cto.com/art/201…

iOS中NSString轉換成HEX(十六進制)-NSData轉換成int

NSString *str "0xff055008"; //先以16為參數告訴strtoul字符串參數表示16進制數字&#xff0c;然后使用0x%X轉為數字類型 unsigned long red strtoul([str UTF8String],0,16); //strtoul如果傳入的字符開頭是“0x”,那么第三個參數是0&#xff0c;也是會轉為十…

spring-boot注解詳解(七)

Configuration 從Spring3.0&#xff0c;Configuration用于定義配置類&#xff0c;可替換xml配置文件&#xff0c;被注解的類內部包含有一個或多個被Bean注解的方法&#xff0c;這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進行…

[pytorch、學習] - 5.2 填充和步幅

參考 5.2 填充和步幅 5.2.1 填充 填充(padding)是指在輸入高和寬的兩側填充元素(通常是0元素)。圖5.2里我們在原輸入高和寬的兩側分別添加了值為0的元素,使得輸入高和寬從3變成了5,并導致輸出高和寬由2增加到4。圖5.2中的陰影部分為第一個輸出元素及其計算所使用的輸入和核數…

java實現Comparable接口和Comparator接口,并重寫compareTo方法和compare方法

原文地址https://segmentfault.com/a/1190000005738975 實體類:java.lang.Comparable(接口) comareTo(重寫方法)&#xff0c;業務排序類 java.util.Comparator(接口) compare(重寫方法). 這兩個接口我們非常的熟悉&#xff0c;但是 在用的時候會有一些不知道怎么下手的感覺&a…

hdu 4714 樹+DFS

題目鏈接&#xff1a;http://acm.hdu.edu.cn/showproblem.php?pid4714 本來想直接求樹的直徑&#xff0c;再得出答案&#xff0c;后來發現是錯的。 思路&#xff1a;任選一個點進行DFS&#xff0c;對于一棵以點u為根節點的子樹來說&#xff0c;如果它的分支數大于1&#xff0c…

springboot----shiro集成

springboot中集成shiro相對簡單&#xff0c;只需要兩個類&#xff1a;一個是shiroConfig類&#xff0c;一個是CustonRealm類。 ShiroConfig類&#xff1a; 顧名思義就是對shiro的一些配置&#xff0c;相對于之前的xml配置。包括&#xff1a;過濾的文件和權限&#xff0c;密碼加…

[pytorch、學習] - 5.3 多輸入通道和多輸出通道

參考 5.3 多輸入通道和多輸出通道 前面兩節里我們用到的輸入和輸出都是二維數組,但真實數據的維度經常更高。例如,彩色圖像在高和寬2個維度外還有RGB(紅、綠、藍)3個顏色通道。假設彩色圖像的高和寬分別是h和w(像素),那么它可以表示為一個3 * h * w的多維數組。我們將大小為3…

非阻塞算法簡介

在不只一個線程訪問一個互斥的變量時&#xff0c;所有線程都必須使用同步&#xff0c;否則就可能會發生一些非常糟糕的事情。Java 語言中主要的同步手段就是 synchronized 關鍵字&#xff08;也稱為內在鎖&#xff09;&#xff0c;它強制實行互斥&#xff0c;確保執行 synchron…

springboot---成員初始化順序

如果我們的類有如下成員變量&#xff1a; Component public class A {Autowiredpublic B b; // B is a beanpublic static C c; // C is also a beanpublic static int count;public float version;public A() {System.out.println("This is A constructor.");}Au…