廢話
最近想整理一波Spring注解相關的文章,雖然寫CURD就只涉及到那些常用的注解。但是筆者我也想去了解一下其他注解,豐富下自己的知識面(提升一下逼格!)。
就想在網上搜了半天,好像大家的都差不多,也找不到原文出處了。這里我就在此基礎上結合相關知識點做一下整理。以便自己或者大家參考查閱了~
幾大常見的注解以及使用
1. @Controller
@Controller:標注一個控制器組件類。標識一個該類是Spring MVC controller處理器,用來創建處理http請求的對象。組合注解(組合了@Component注解),應用在MVC層(控制層)
@Controller
public class TestController {
@RequestMapping("/test")
public String test(String name){
return "hello";
}
}
2. @RestController
Spring4
之后加入的注解,原來在@Controller
中返回json
需要@ResponseBody
來配合,如果直接用@RestController
替代@Controller
就不需要再配置@ResponseBody
,默認返回json格式。
@RestController
public class TestController {
@RequestMapping("/test")
public String test(String name){
return "hello";
}
}
3. @Service
@Service 把類當做容器中的一個組件來使用。
當使用@Autowired注解則是實例化構造器。因為在自動注入時,是一個接口類型,所以要在容器中找到相應的實現類注入。故@Service加到類上。組合注解(組合了@Component注解),應用在service層(業務邏輯)。
@Service
public interface UserService {
User login(String username,String password);
}
//當把注解寫在接口上時,spring容器會注入失敗。
//注解寫在類上 注入不會失敗。
@Service
public class UserServiceImpl implements UserService{
@Autowired
private UserMapper userMapper;
}
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService
}
4. @Reponsitory
@Repository注解便屬於最先引入的一批,它用於將數據訪問層 (DAO 層 ) 的類標識為 Spring Bean。具體只需將該注解標注在 DAO類上即可。為什么 @Repository 只能標注在 DAO 類上呢?這是因為該注解的作用不只是將類識別為Bean,同時它還能將所標注的類中拋出的數據訪問異常封裝為 Spring 的數據訪問異常類型。 Spring本身提供了一個豐富的並且是與具體的數據訪問技術無關的數據訪問異常結構,用於封裝不同的持久層框架拋出的異常,使得異常獨立於底層的框架。組合注解(組合了@Component注解),應用在DAO層(數據訪問層)。
5. @Component
把普通pojo實例化到spring容器中,相當於配置文件中的
6. @Configuration
@Configuration作用在類上,聲明一個class需要被spring解析以擴充beanDefinition。
@Configration注解同時被@Component注解修飾,因此具有被自動加載的特點,被@Configuration修飾的類本身也會作為definition注冊。value屬性是Configuration bean名稱。
7. @Resource
這個注解屬於J2EE的。@Resource
的作用相當於@Autowired
,只不過@Autowired
按byType
自動注入,而@Resource
默認按 byName
自動注入罷了。@Resource
有兩個屬性是比較重要的,分是name和type,Spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。所以如果使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。如果既不指定name也不指定type屬性,這時將通過反射機制使用byName自動注入策略。
@Resource裝配順序
- 如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常
- 如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常
- 如果指定了type,則從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常
- 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配;
8. @Bean
Spring的@Bean注解用於告訴方法,產生一個Bean對象,然后這個Bean對象交給Spring管理。產生這個Bean對象的方法Spring只會調用一次,隨后這個Spring將會將這個Bean對象放在自己的IOC容器中。
SpringIOC 容器管理一個或者多個bean,這些bean都需要在@Configuration注解下進行創建,在一個方法上使用@Bean注解就表明這個方法需要交給Spring進行管理。
詳細了解@Bean 注解全解析:https://www.cnblogs.com/cxuanBlog/p/11179439.html
9.@Value
值得注入。經常與Spring EL表達式語言一起使用,注入普通字符,系統屬性,表達式運算結果,其他Bean的屬性,文件內容,網址請求內容,配置文件屬性值等等。
主要兩種使用方法:
- @Value("#{configProperties['key']}")
- @Value("${key}")
10. @PropertySource
指定文件地址。提供一種方便的、聲明性的機制,用於向Spring環境添加PropertySource。與@Configuration類一起使用。在app項目中,我們通過@PropertySource注解到JavaConfig類上,設置.properties配置文件的路徑。
@Component
@PropertySource(value = "application.properties")
public class Message {
@Value("${demo.msg}")
private String msg;
}
11.@ResponseBody
@ResponseBody
注解表示該方法的返回的結果直接寫入HTTP響應正文中(ResponseBody),一般在異步獲取數據時使用,通常是在使用@RequestMapping
后。返回值通常解析為跳轉路徑,加上@ResponseBody
后返回結果不會被解析為跳轉路徑,而是直接寫入HTTP
響應正文中。
12.@RequestMapping
使用 @RequestMapping
來映射 Request
請求與處理器,通過這個注解可以定義不同的處理器映射規則,即為控制器指定可以處理哪些URL請求。
用@RequestMapping
來映射URL
到控制器類,或者是到Controller
控制器的處理方法上。
當@RequestMapping
標記在Controller
類上的時候,里面使用@RequestMapping
標記的方法的請求地址都是相對於類上的@RequestMapping 而言的;
當Controller
類上沒有標記@RequestMapping
注解時,方法上的@RequestMapping
都是絕對路徑。這種絕對路徑和相對路徑所組合成的最終路徑都是相對於根路徑“/ ”而言的。
13. @SpringBootApplication
@SpringBootApplication
是一個組合注解
源碼如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
excludeFilters = {
@Filter(type = FilterType.CUSTOM,classes = {TypeExcludeFilter.class}),
@Filter( type = FilterType.CUSTOM,classes = {AutoConfigurationExcludeFilter.class})
}
)
public @interface SpringBootApplication {
}
由源碼可知,主要包含三個注解@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan。
14. @ComponentScan
-
@ComponentScan
(包掃描)component是組件,scan是掃描,所以這個注解的含義就是用來掃描組件的 -
ComponentScan就是掃描所標注的類所在包下的所有需要注入的組件,將其注入,這里他是在@SpringBootApplication 中體現的,所以這個注解會自動注入所有在主程序所在包下的組件
-
以前在ssm項目中我們需要去配置我們的包掃描,相對應的XML配置就是context:component-scan/, 將符合條件的組件加入到IOC容器中。
詳細了解點擊:https://blog.csdn.net/luojinbai/article/details/85877956
15.@EnableAutoConfiguration
@EnableAutoConfiguration
表示開啟自動裝配,注解主要作用從classpath中搜尋所有的META-INF/spring.factories配置文件,並將其中的org.spring-framework.boot.autoconfigure.EnableAutoConfiguration對應的配置項通過反射實例化為對應的標注了@Configuration的javaConfig形式的IOC容器配置類,然后匯總為一整個並加載到IOC容器。
源碼如下:
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import({AutoConfigurationImportSelector.class})
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
Class<?>[] exclude() default {};
String[] excludeName() default {};
}
其中兩個比較重要的注解@AutoConfigurationPackage
與@Import({AutoConfigurationImportSelector.class})
@AutoConfigurationPackage
表示獲取我們注解所在包下的組件去進行注冊@Import({AutoConfigurationImportSelector.class})
表示自動配置導入選擇器,從META-INF/spring.factories獲取我們的自動配置信息的
較為重要注解以及使用
1. @ConfigurationProperties
將properties屬性與一個Bean及其屬性相關聯,從而實現類型安全的配置。例如:@ConfigurationProperties(prefix="connection")
@Data// lombok注解,相關知識可以自行查閱
@Component
@ConfigurationProperties(prefix="connection")
public class ConnectionSettings {
private String username;
private String remoteAddress;
private String password ;
}
詳細內容可參考:https://blog.csdn.net/fcvtb/article/details/97488297
2. @ConditionalOnBean與@ConditionalOnMissingBean
@ConditionalOnBean
與@ConditionalOnMissingBean
兩個注解都是條件注解,作用相反。
@ConditionalOnBean
表示存當給定的在bean存在時,則實例化當前Bean。@ConditionalOnMissingBean
表示當給定的在bean不存在時,則實例化當前Bean。
@ConditionalOnBean:
結合使用注解@ConditionalOnBean
和@Bean
,可以做到只有特定名稱或者類型的Bean
存在於BeanFactory
時才創建某個Bean。例如:
@Configuration
public class ConditionalOnBeanConfig {
@Bean
public A beanA(){
return new A(); // 創建一個Bean,名稱是 beanA,不需要滿足什么前置條件,
}
@Bean
@ConditionalOnBean(name="beanA")
public B beanB(){
// 僅在beanFactory存在一個名稱叫做beanA的bean時,當前方法初始化一個名字為beanB的bean。
return new B();
}
@Bean
@ConditionalOnBean
public C beanC(){
//如果beanFactory不存在一個類型為C的bean,則不創建該bean。
// 如果當前項目僅有這一個 bean 配置文件,則因為 beanFactory 中不存在一個類型為C的 bean ,所以當前
// 方法定義的名稱為 beanC 的 bean 並不會被初始化。
return new C();
}
@Bean
public SimpleInt beanAInt(){
// 創建一個類型為 SimpleInt 的 bean ,其實現類使用 ASimpleInt
return new ASimpleInt();
}
@Bean
@ConditionalOnBean
public SimpleInt beanBInt(){
// 僅在 beanFactory 中存在一個類型為 SimpleInt 的 bean 時才初始化一個類型同樣 為 SimpleInt
// 的 bean ,bean 名稱為 beanBInt
return new BSimpleInt();
}
}
@ConditionalOnMissingBean
配置類中有兩個Computer類的bean,一個是筆記本電腦,一個是備用電腦。如果當前容器中已經有電腦bean了,就不注入備用電腦,如果沒有,則注入備用電腦,這里需要使用到@ConditionalOnMissingBean。
@Configuration
public class BeanConfig {
@Bean(name = "notebookPC")
public Computer computer1(){
return new Computer("筆記本電腦");
}
@ConditionalOnMissingBean(Computer.class)
@Bean("reservePC")
public Computer computer2(){
return new Computer("備用電腦");
}
}
3. @ConditionalOnClass與@ConditionalOnMissingClass
@ConditionalOnClass
與@ConditionalOnMissingClass
這兩個注解與@ConditionalOnBean與@ConditionalOnMissingBean兩個注解相似。
- @ConditionalOnClass 表示當給定的類名在類路徑上存在,則實例化當前Bean
- @ConditionalOnMissingClass 表示當給定的類名在類路徑上不存在,則實例化當前Bean
其他
@ConditionalOnSingleCandidate : DI容器中該類型Bean只有一個或@Primary的只有一個時起效
@ConditionalOnExpression : SpEL表達式結果為true時
@ConditionalOnProperty : 參數設置或者值一致時起效
@ConditionalOnResource : 指定的文件存在時起效
@ConditionalOnJndi : 指定的JNDI存在時起效
@ConditionalOnJava : 指定的Java版本存在時起效
@ConditionalOnWebApplication : Web應用環境下起效
@ConditionalOnNotWebApplication : 非Web應用環境下起效
以上注解都是條件注解,作用類似。這里就不做過多介紹了~~
有興趣的朋友可自行查閱官網:https://spring.io/
推薦
大廠筆試內容集合(內有詳細解析) 持續更新中....
文末
歡迎關注個人微信公眾號:Coder編程
歡迎關注Coder編程公眾號,主要分享數據結構與算法、Java相關知識體系、框架知識及原理、Spring全家桶、微服務項目實戰、DevOps實踐之路、每日一篇互聯網大廠面試或筆試題以及PMP項目管理知識等。更多精彩內容正在路上~
文章收錄至
Github: https://github.com/CoderMerlin/coder-programming
Gitee: https://gitee.com/573059382/coder-programming
歡迎關注並star~