SpringBoot進階教程(六十四)註解大全
在Spring1.x時代,還沒出現註解,需要大量xml配置檔案並在內部編寫大量bean標籤。Java5推出新特性annotation,為spring的更新奠定了基礎。從Spring 2.X開始spring將xml配置中的物件ioc過程轉化成了註解。Spring Boot之所以能夠輕鬆地實現應用的建立及與其他框架快速整合,最核心的原因就在於它極大地簡化了專案的配置,最大化地實現了“約定大於配置”的原則。但是註解種類之繁多,還能容易引起混淆,這才有了本文《SpringBoot進階教程(六十四)註解大全》。
要想對SpringBoot註解有個更全面更清晰的認識,就需要分個類,分別是Spring註解、Spring Web註解、Spring Boot註解、Spring Scheduling註解和註解集合。大致可以將註解分為5大類,其中前4類是為了便於理解,分別從4個類別中抽取了一些單獨介紹。而最後一個為註解集合,即可能會包含前面4種註解。
vSpring註解
在Spring Core註解中,主要討論Spring DI和Spring IOC中使用的Spring核心註釋。眾所周知,Spring DI和Spring IOC是Spring框架的核心概念。所以介紹 org.springframework.beans.factory.annotation
和 org.springframework.context.annotation
包中的註解。這兩個包中註解有很多,就抽取其中的15個註解。
Spring Core Annotations:
- @Autowired
- @Qualifier
- @Bean
- @Required
- @Value
- @DependsOn
- @Lazy
- @Lookup
- @Primary
- @Scope
- @Profile
- @Import
- @ImportResource
- @PropertySource
- @PropertySources
單單 org.springframework.context.annotation
這個包下面,註解就有這老些,所以很難列出所有註解舉例,只能抽一些常用的。文末會給出其它註解的作用和定義(儘量給全)。
1.1 @Autowired
@Autowired是一種註解,可以對成員變數、方法和建構函式進行標註,來完成自動裝配的工作,@Autowired標註可以放在成員變數上,也可以放在成員變數的set方法上,也可以放在任意方法上表示,自動執行當前方法,如果方法有引數,會在IOC容器中自動尋找同類型引數為其傳值。
這裡必須明確:@Autowired是根據型別進行自動裝配的,如果需要按名稱進行裝配,則需要配合@Qualifier使用;
1.1.1 構造器注入
@RestController public class UserController { private UserService userService; @Autowired public UserController(UserService userService) { this.userService = userService; } }
1.1.2 setter方法注入
@RestController public class UserController { private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } }
1.1.3 field反射注入
@RestController public class UserController { @Autowired private UserService userService; }
1.2 @Qualifier
上面已經說到@Autowired按型別裝配Spring Bean。如果容器中有多個相同型別的bean,則框架將丟擲NoUniqueBeanDefinitionException, 以提示有多個滿足條件的bean進行自動裝配。程式無法正確做出判斷使用哪一個,通過將@Qualifier註解與我們想要使用的特定Spring bean的名稱一起進行裝配,Spring框架就能從多個相同型別並滿足裝配要求的bean中找到我們想要的,
@Component("studentInfo") public class StudentInfo implements UserInfo { public String userName() { return "student"; } } @Component("teacherInfo") public class TeacherInfo implements UserInfo { public String userName { return "teacher"; } } @Component public class UserService { @Autowired @Qualifier("studentInfo") private UserInfo userInfo; //todo }
1.3 @Bean
@Bean是一個方法級別上的註解,主要用在@Configuration註解的類裡,也可以用在@Component註解的類裡。新增的bean的id為方法名。
@Configuration public class BeanConfig { @Bean public Person userInfo() { return new UserInfo("toutou", 18); } }
這個配置就等同於之前在xml裡的配置:
<bean id="userInfo" class="com.test.UserInfo"> <property name="age" value="18"/> <property name="name" value="請叫我頭頭哥 http://toutou.cnblogs.com"/> </bean>
1.4 @Required
@Required 註釋應用於 bean 屬性的 setter 方法,它表明受影響的 bean 屬性在配置時必須放在 XML 配置檔案中,否則容器就會丟擲一個 BeanInitializationException 異常。
@Required void setUserName(String name) { this.name = name; }
<bean class="com.test.UserInfo"> <property name="name" value="請叫我頭頭哥 https://www.cnblogs.com/toutou/" /> </bean>
1.5 @Value
@Value將外部的值動態注入到Bean中。"注入外部的值"可以有很多種,它可以注入普通字串、注入java 系統變數、注入表示式結果、注入其他Bean屬性、將配置檔案 *.properties 或 *. yml 裡 配置的 屬性 注入、注入檔案資源和注入url資源等。
1.6 @DependsOn
Spring容器載入bean順序是不確定的,Spring框架也沒有約定特定載入順序邏輯規範。@DependsOn註解可以定義在類和方法上,比如說A元件要依賴於B元件,那就是B元件需要比A元件先註冊到IOC容器中。
public class FirstBean { @Autowired private SecondBean secondBean; } public class SecondBean { public SecondBean() { System.out.println("SecondBean init"); } }
@Configuration public class BeanConfig { @Bean("firstBean") @DependsOn(value = { "secondBean" }) public FirstBean firstBean() { return new FirstBean(); } @Bean("secondBean") public SecondBean secondBean() { return new SecondBean(); } }
1.7 @Lazy
@Lazy註解用於標識bean是否需要延遲載入。Spring IoC容器一般都會在啟動的時候例項化所有單例項bean,如果想要Spring在啟動的時候延遲載入A,即在呼叫B的時候再去初始化,則可以使用@Lazy註解。
public class FirstBean { public void test() { System.out.println("FirstBean Class"); } } public class SecondBean { public void test() { System.out.println("SecondBean Class"); } }
@Configuration public class AppConfig { @Lazy(value = true) @Bean public FirstBean firstBean() { return new FirstBean(); } @Bean public SecondBean secondBean() { return new SecondBean(); } }
1.8 @Lookup
@Lookup的註解是一個作用在方法上的註解,被其標註的方法會被重寫,然後根據其返回值的型別,容器呼叫BeanFactory的getBean()方法來返回一個bean。
1.9 @Primary
@Primary與@Qualifier類似,都是解決@Autowired時容器中有多個相同型別bean的問題,Primary可以理解為預設優先選擇,同時不可以同時設定多個。
@Component("studentInfo") public class StudentInfo implements UserInfo { public String userName() { return "student"; } } @Component("teacherInfo") @Primary public class TeacherInfo implements UserInfo { public String userName { return "teacher"; } } @Component public class UserService { @Autowired @Qualifier("studentInfo") private UserInfo userInfo; //todo }
1.10 @Scope
@Scope註解是springIoc容器中的一個作用域,在 Spring IoC 容器中具有以下幾種作用域:基本作用域singleton(單例)(預設作用域)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定義作用域
1.11 @Profile
@profile註解的作用是為了應對多環境開發,比如開發環境使用dev, 生產環境使用prod,就可以使用@Profile註解實現不同的開發環境使用不同的資料來源。spring3.2之前 @Profile註解用在類上,spring3.2 之後 @Profile註解用在方法上
1.12 @Import
@Import用於注入指定的類,匯入元件id預設是元件的全類名。
@Configuration public class ConfigA { @Bean public A a() { return new A(); } } @Configuration @Import(ConfigA.class) public class ConfigB { @Bean public B b() { return new B(); } }
1.13 @ImportResource
@ImportResource註解用於匯入Spring的配置檔案,讓配置檔案裡面的內容生效;(就是以前寫的springmvc.xml、applicationContext.xml)
@Configuration @ImportResource({"classpath*:applicationContext.xml"}) public class XmlConfiguration { }
1.14 @PropertySource
@PropertySource註解載入指定的配置檔案
@Configuration @PropertySource("classpath:config.properties") public class ProperySourceDemo implements InitializingBean { @Autowired Environment env; @Override public void afterPropertiesSet() throws Exception { setDatabaseConfig(); } private void setDatabaseConfig() { DataSourceConfig config = new DataSourceConfig(); config.setDriver(env.getProperty("jdbc.driver")); config.setUrl(env.getProperty("jdbc.url")); config.setUsername(env.getProperty("jdbc.username")); config.setPassword(env.getProperty("jdbc.password")); System.out.println(config.toString()); } }
1.15 @PropertySources
@PropertySources顧名思義就是可以指定多個@PropertySource來匯入配置檔案。
@PropertySources({ @PropertySource("classpath:config.properties"), @PropertySource("classpath:db.properties") }) public class AppConfig { //todo... }
vSpring Web註解
2.1 @RequestBody
主要用來接收前端傳遞給後端的json字串中的資料的。
@RestController @RequestMapping("/api/v1") public class UserController { @Autowired private UserService userService; @PostMapping("/user") public UserInfo createUser(@Valid @RequestBody UserInfo user) { return userService.save(user); } }
2.2 @RequestMapping
@RequestMapping是一個用來處理請求地址對映的註解,可用於類或方法上。也就是通過它來指定控制器可以處理哪些URL請求。
@Controller class UserController { @RequestMapping(value = "/user/index", method = RequestMethod.GET) String index() { return "index"; } }
2.3 @GetMapping
@GetMapping註釋將Http GET請求對映到特定的處理程式方法。 它是一個組合的註釋,@RequestMapping(method = RequestMethod.GET)的快捷方式。
@GetMapping("/users") public List<user> getAllUser() { //... } @GetMapping("/users/{id}") public ResponseEntity<User> getUserById(@PathVariable(value = "id") Long userId) throws ResourceNotFoundException { user user = userRepository.findById(userId) .orElseThrow(() -> new ResourceNotFoundException("user not found for this id :: " + userId)); return ResponseEntity.ok().body(user); }
2.4 @PathVariable
@PathVariable是spring3.0的一個新功能:接收請求路徑中佔位符的值
2.5 @PostMapping
@PostMapping註釋將HTTP POST請求對映到特定的處理程式方法。 它是一個組合的註釋,@RequestMapping(method = RequestMethod.POST)的快捷方式。
@PostMapping("/user/add") public User addUser(@Valid @RequestBody User user) { return userRepository.save(user); }
其它擴充套件: @PutMapping、@DeleteMapping、@PatchMapping(這三種相對用的比較少,一筆帶過。)
2.6 @ControllerAdvice
增強型控制器,對於控制器的全域性配置放在同一個位置。可以用於定義@ExceptionHandler、@InitBinder、@ModelAttribute,可處理全域性異常處理、全域性資料繫結和全域性資料預處理。
@ControllerAdvice(basePackages = {"com.toutou.controller"} ) public class GlobalControllerAdvice { @InitBinder public void dataBinding(WebDataBinder binder) { SimpleDateFormat dateFormat = new SimpleDateFormat("dd/MM/yyyy"); dateFormat.setLenient(false); binder.registerCustomEditor(Date.class, "dob", new CustomDateEditor(dateFormat, true)); } @ModelAttribute public void globalAttributes(Model model) { model.addAttribute("msg", "Hello World!"); } @ExceptionHandler(FileNotFoundException.class) public ModelAndView myError(Exception exception) { ModelAndView mav = new ModelAndView(); mav.addObject("exception", exception); mav.setViewName("error"); return mav; } }
2.7 @ExceptionHandler
@ExceptionHandler統一處理某一類異常,從而能夠減少程式碼重複率和複雜度。
2.8 @InitBinder
@InitBinder只在@Controller中註解方法來為這個控制器註冊一個繫結器初始化方法,方法只對本控制器有效。
2.9 @ModelAttribute
@ModelAttribute註解用於將方法的引數或方法的返回值繫結到指定的模型屬性上,並返回給Web檢視。
2.10 @ResponseBody
@ResponseBody將controller裡方法返回的物件通過適當的轉換器轉換為Json寫入到response物件的body區.
2.11 @Controller
@Controller用於標記在一個類上,使用它標記的類就是一個SpringMvc Controller物件,分發處理器會掃描使用該註解的類的方法,並檢測該方法是否使用了@RequestMapping註解。
2.12 @RestController
@RestController在Spring中的作用等同於@Controller + @ResponseBody。
2.13 @RequestParam
@RequestParam將請求引數繫結到你控制器的方法引數上(是springmvc中接收普通引數的註解)
2.14 @CrossOrigin
@CrossOrigin支援跨域,可用於Controller上,也可用於方法上。
@CrossOrigin(origins = "http://toutou.com", maxAge = 3600) @RequestMapping("/index") String index() { return "Hello World!"; }
vSpring Boot註解
3.1 @SpringBootApplication
@SpringBootApplication是Sprnig Boot專案的核心註解,目的是開啟自動配置。由於@Configuration,@EnableAutoConfiguration和@ComponentScan三個註解一般都是一起使用,於是spring boot提供了一個統一的註解@SpringBootApplication。即:@SpringBootApplication=@Configuration + @EnableAutoConfiguration + @ComponentScan。
@SpringBootApplication // 等於:@Configuration @EnableAutoConfiguration @ComponentScan public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
如上程式碼,是不是簡潔了不少。
3.2 @EnableAutoConfiguration
可以根據classpath中的jar依賴,自動註冊bean,一般用於類或介面上,它嘗試根據您新增的jar依賴項自動配置Spring應用程式。自動載入應用程式所需的所有Bean——這依賴於Spring Boot在類路徑中的查詢。
@EnableAutoConfiguration public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
3.3 @ConditionalOnClass、@ConditionalOnMissingClass
3.4 @ConditionalOnBean、@ConditionalOnMissingBean
@ConditionalOnBean // 當給定的在bean存在時,則例項化當前Bean @ConditionalOnMissingBean // 當給定的在bean不存在時,則例項化當前Bean @ConditionalOnClass // 當給定的類名在類路徑上存在,則例項化當前Bean @ConditionalOnMissingClass // 當給定的類名在類路徑上不存在,則例項化當前Bean
3.5 @ConditionalOnProperty
@ConditionalOnProperty可以通過配置檔案中的屬性值來判定configuration是否被注入。
3.6 @ConditionalOnResource
@ConditionalOnResource是註解在Configuration bean上,在其載入之前對指定資源進行校驗,是否存在,如果不存在,丟擲異常;該註解支援傳入多個變數,
3.7 @ConditionalOnWebApplication、@ConditionalOnNotWebApplication
@ConditionalOnWebApplication主要的用處是: 當Spring為web服務時,才使註解的類生效;通常是配置類;@ConditionalOnNotWebApplication不是web應用。
3.8 @Conditional
@Conditional的作用是按照一定的條件進行判斷,滿足條件給容器註冊bean。
vSpring Scheduling註解
4.1 @Scheduled
@Scheduled可以作為一個觸發源新增到一個方法中。
@Scheduled(fixedDelay=1000) public void doSomething() { //... }
4.2 @EnableScheduling
@EnableScheduling 在配置類上使用,開啟計劃任務的支援(類上)。
@Configuration @EnableScheduling //通過@EnableScheduling註解開啟對計劃任務的支援 public class TaskScheduleConfig { //... }
4.3 @Async
@Async標註的方法,稱之為非同步方法;這些方法將在執行的時候,將會在獨立的執行緒中被執行,呼叫者無需等待它的完成,即可繼續其他的操作。有時候我們會呼叫一些特殊的任務,任務會比較耗時,重要的是,我們不管他返回的後果。這時候我們就需要用這類的非同步任務啦。
4.4 @EnableAsync
@EnableAsync註解啟用了Spring非同步方法執行功能
@Schedules
@Schedules作用跟@Scheduled一樣,@Schedules內部包含多個@Scheduled註解,可以表示一個方法可以存在多個排程設定。
v註解集合
@ComponentScan:表示將該類自動發現掃描元件。個人理解相當於,如果掃描到有@Component、@Controller、@Service等這些註解的類,並註冊為Bean,可以自動收集所有的Spring元件,包括@Configuration類。我們經常使用@ComponentScan註解搜尋beans,並結合@Autowired註解匯入。可以自動收集所有的Spring元件,包括@Configuration類。我們經常使用@ComponentScan註解搜尋beans,並結合@Autowired註解匯入。如果沒有配置的話,Spring Boot會掃描啟動類所在包下以及子包下的使用了@Service,@Repository等註解的類。
@Repository:使用@Repository註解可以確保DAO或者repositories提供異常轉譯,這個註解修飾的DAO或者repositories類會被ComponetScan發現並配置,同時也不需要為它們提供XML配置項。
@Inject:等價於預設的@Autowired,只是沒有required屬性;
@Component:泛指元件,當元件不好歸類的時候,我們可以使用這個註解進行標註。
@JsonBackReference:解決巢狀外鏈問題。
@JsonIgnore:作用是json序列化時將Java bean中的一些屬性忽略掉,序列化和反序列化都受影響。
@ConfigurationProperties:Spring Boot可使用註解的方式將自定義的properties檔案對映到實體bean中,比如config.properties檔案。
@ConditionalOnSingleCandidate:組合@Conditional註解,當指定的class在容器中只有一個Bean,或者同時有多個但為首選時才開啟配置。
@ConditionalOnCloudPlatform:組合 @Conditional 註解,當指定的雲平臺啟用時才開啟配置。
@ConditionalOnJndi:組合 @Conditional 註解,當指定的 JNDI 存在時才開啟配置。
@ConditionalOnJava:組合@Conditional 註解,當執行的 Java JVM 在指定的版本範圍時才開啟配置。
@ConditionalOnExpression:組合 @Conditional 註解,當 SpEL 表示式為 true 時才開啟配置。
@WiselyConfiguration: 組合註解可以替代@Configuration和@ComponentScan
@Transcational: 事務處理
@Target (ElementType.TYPE):元註解,用來指定註解修飾類的那個成員 -->指定攔截規則
@Cacheable: 資料快取
@ActiveProfiles: 用來宣告活動的 profile
@RunWith: 執行器
其他參考/學習資料:
- Spring Boot Annotations
- Spring Boot Annotations - HowToDoInJava
- springboot註解
- SpringBoot三大註解
- Frequently Used Annotations in Spring Boot Applications
- Spring MVC Annotations with Examples
v原始碼地址
https://github.com/toutouge/javademosecond/tree/master/hellospringboot
作 者:請叫我頭頭哥
出 處:http://www.cnblogs.com/toutou/
關於作者:專注於基礎平臺的專案開發。如有問題或建議,請多多賜教!
版權宣告:本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段宣告,且在文章頁面明顯位置給出原文連結。
特此宣告:所有評論和私信都會在第一時間回覆。也歡迎園子的大大們指正錯誤,共同進步。或者直接私信我
聲援博主:如果您覺得文章對您有幫助,可以點選文章右下角【推薦】一下。您的鼓勵是作者堅持原創和持續寫作的最大動力!