目錄
@Repository/@Service/@Controller
@GetMapping/@PostMapping/@PutMapping/@PatchMapping/@DeleteMapping
一、註冊Bean
@Component
所有受Spring管理組件的通用形式
@Repository/@Service/@Controller
分別對應持久層/服務層/控制層的Bean註冊,內部也是由@Component實現
package org.springframework.stereotype;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Indicates that an annotated class is a "Controller" (e.g. a web controller).
*
* <p>This annotation serves as a specialization of {@link Component @Component},
* allowing for implementation classes to be autodetected through classpath scanning.
* It is typically used in combination with annotated handler methods based on the
* {@link org.springframework.web.bind.annotation.RequestMapping} annotation.
*
* @author Arjen Poutsma
* @author Juergen Hoeller
* @since 2.5
* @see Component
* @see org.springframework.web.bind.annotation.RequestMapping
* @see org.springframework.context.annotation.ClassPathBeanDefinitionScanner
*/
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
@Repository/@Service與@Controller代碼結構相同,不再展示。
@RestController
Spring4之後加入的註解,@Controller+@ResponseBody來配合,默認返回json格式
使用該註解後就不需要再使用@ResponseBody
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Controller;
/**
* A convenience annotation that is itself annotated with
* {@link Controller @Controller} and {@link ResponseBody @ResponseBody}.
* <p>
* Types that carry this annotation are treated as controllers where
* {@link RequestMapping @RequestMapping} methods assume
* {@link ResponseBody @ResponseBody} semantics by default.
*
* <p><b>NOTE:</b> {@code @RestController} is processed if an appropriate
* {@code HandlerMapping}-{@code HandlerAdapter} pair is configured such as the
* {@code RequestMappingHandlerMapping}-{@code RequestMappingHandlerAdapter}
* pair which are the default in the MVC Java config and the MVC namespace.
*
* @author Rossen Stoyanchev
* @author Sam Brannen
* @since 4.0
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
* @since 4.0.1
*/
@AliasFor(annotation = Controller.class)
String value() default "";
}
二、注入Bean
@Autowired
默認情況下,@Autowired默認是根據類型(byType)進行自動裝配的,是Spring自帶的註解。
如果容器中有多個相同類型的bean,則框架將拋出NoUniqueBeanDefinitionException,以提示有多個滿足條件的bean進行自動裝配,程序無法正確做出判斷使用哪一個。
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* Declares whether the annotated dependency is required.
* <p>Defaults to {@code true}.
*/
boolean required() default true;
}
@Autowired中required屬性默認爲true,此時如果容器中沒有對應的bean,則拋出NoSuchBeanDefinitionException
可以配置爲false,這樣當沒有找到相應bean的時候系統不會拋異常
@Qualifier
使用@Autowired時,如果有多個類型一樣的Bean,需要指定按照名稱(byName)進行裝配,則需要配合@Qualifier。
該註解是用來消除依賴注入衝突的。當@Autowired 和 @Qualifier 結合使用時,自動注入的策略就從byType轉變成byName 了。另外,需要在註冊Bean的註解中聲明value屬性以確定名稱。
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
@Resource
默認根據屬性名稱進行自動裝配的,如果沒有匹配,則根據類型進行匹配,如果有多個類型一樣的Bean候選者,則可以通過name進行指定進行注入,是JSR250規範的實現。
如果指定了name,則查找名稱匹配的bean進行裝配,找不到則拋出異常
如果指定了type,則查找類型匹配的唯一bean進行裝配,找不到或者找到多個,都會拋出異常
如果同時指定name和type,則找到唯一的bean進行裝配,找不到則拋出異常
package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
String name() default "";
String lookup() default "";
Class<?> type() default java.lang.Object.class;
enum AuthenticationType {
CONTAINER,
APPLICATION
}
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
boolean shareable() default true;
String mappedName() default "";
String description() default "";
}
@Inject
根據類型進行自動裝配的,如果需要按名稱進行裝配,則需要配合@Named(相當於@Qualifier),是JSR330中的規範
對比:
@Autowired、@Inject是默認按照byType匹配的,@Autowired+@Qualifier實現byName,@Inject+@Name實現byName
@Resource是按照名稱匹配的,通過name屬性進行指定
@Autowired是Spring的,@Resource是JSR250規範的,@Inject是JSR330規範的
三、Controller參數接收
@RequestParam
此註解用在請求方法的參數上,用於將http請求參數(Param)的值賦值給方法中的形參。
處理Content-Type: 爲 application/x-www-form-urlencoded
編碼的內容
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.Map;
import org.springframework.core.annotation.AliasFor;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* The name of the request parameter to bind to.
* @since 4.2
*/
@AliasFor("value")
String name() default "";
/**
* Whether the parameter is required.
* <p>Defaults to {@code true}, leading to an exception being thrown
* if the parameter is missing in the request. Switch this to
* {@code false} if you prefer a {@code null} value if the parameter is
* not present in the request.
* <p>Alternatively, provide a {@link #defaultValue}, which implicitly
* sets this flag to {@code false}.
*/
boolean required() default true;
/**
* The default value to use as a fallback when the request parameter is
* not provided or has an empty value.
* <p>Supplying a default value implicitly sets {@link #required} to
* {@code false}.
*/
String defaultValue() default ValueConstants.DEFAULT_NONE;
}
@RequestBody
此註解用在請求方法的參數上,用於將http請求體(Body)映射綁定到方法中的形參。
接收json格式的數據,並轉換成對應的數據類型。
常用來處理Content-Type: application/json, application/xml等編碼的內容;
也可以處理Content-Type: 爲 application/x-www-form-urlencoded
編碼的內容。
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.http.converter.HttpMessageConverter;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
/**
* Whether body content is required.
* <p>Default is {@code true}, leading to an exception thrown in case
* there is no body content. Switch this to {@code false} if you prefer
* {@code null} to be passed when the body content is {@code null}.
* @since 3.2
*/
boolean required() default true;
}
@ModelAttribute
此註解用在請求方法的參數上,用於將參數綁定到Model對象
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.ui.Model;
@Target({ElementType.PARAMETER, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* The name of the model attribute to bind to.
* <p>The default model attribute name is inferred from the declared
* attribute type (i.e. the method parameter type or method return type),
* based on the non-qualified class name:
* e.g. "orderAddress" for class "mypackage.OrderAddress",
* or "orderAddressList" for "List<mypackage.OrderAddress>".
* @since 4.3
*/
@AliasFor("value")
String name() default "";
/**
* Allows declaring data binding disabled directly on an {@code @ModelAttribute}
* method parameter or on the attribute returned from an {@code @ModelAttribute}
* method, both of which would prevent data binding for that attribute.
* <p>By default this is set to {@code true} in which case data binding applies.
* Set this to {@code false} to disable data binding.
* @since 4.3
*/
boolean binding() default true;
}
@PathVariable
spring3.0的新功能:接收請求路徑中佔位符的值
舉個例子
127.0.0.1:8080/project/get/1 使用@PathVariable
@GetMapping("/get/{id}")
public Object getObject(@PathVariable String id) {}
127.0.0.1:8080/project/get?id=1 使用@RequestParam
@GetMapping("/get")
public Object getObject (@RequestParam String id) {}
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* The name of the path variable to bind to.
* @since 4.3.3
*/
@AliasFor("value")
String name() default "";
/**
* Whether the path variable is required.
* <p>Defaults to {@code true}, leading to an exception being thrown if the path
* variable is missing in the incoming request. Switch this to {@code false} if
* you prefer a {@code null} or Java 8 {@code java.util.Optional} in this case.
* e.g. on a {@code ModelAttribute} method which serves for different requests.
* @since 4.3.3
*/
boolean required() default true;
}
四、配置
@Configuration
聲明當前類爲配置類,相當於xml形式的Spring配置。內部有@Component,表明這個類也是一個bean
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.annotation.AliasFor;
import org.springframework.stereotype.Component;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Configuration {
@AliasFor(annotation = Component.class)
String value() default "";
}
@Bean
聲明當前方法的返回值爲一個bean,相當於xml配置中的bean標籤
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
@AliasFor("name")
String[] value() default {};
@AliasFor("value")
String[] name() default {};
@Deprecated
Autowire autowire() default Autowire.NO;
boolean autowireCandidate() default true;
String initMethod() default "";
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}
@Primary
當返回多個Bean時,使用@Primary註解表明當前Bean爲默認優先選擇,不可以同時設置多個
package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Primary {
}
舉個例子
@Primary
@Bean
public Queue MessageQueue() {
return new ActiveMQQueue("msgQue");
}
五、屬性注入
@Value
package org.springframework.beans.factory.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
* The actual value expression: for example {@code #{systemProperties.myProp}}.
*/
String value();
}
六、事務
@Transactional
7種事務的傳播機制
-
REQUIRED:默認機制,支持使用當前事務,如果當前事務不存在,創建一個新事務。
-
SUPPORTS:支持使用當前事務,如果當前事務不存在,則不使用事務。
-
MANDATORY:支持使用當前事務,如果當前事務不存在,則拋出Exception。
-
REQUIRES_NEW:創建一個新事務,如果當前事務存在,把當前事務掛起。
-
NOT_SUPPORTED:無事務執行,如果當前事務存在,把當前事務掛起。
-
NEVER:無事務執行,如果當前有事務,則拋出Exception。
-
NESTED:嵌套事務,如果當前事務存在,那麼在嵌套的事務中執行。如果當前事務不存在,則表現跟REQUIRED一樣。
4種隔離級別
事務隔離級別 | 髒讀 | 不可重複讀 | 幻讀 |
讀未提交(Read-Uncommitted) | 是 | 是 | 是 |
不可重複讀(Read-Committed) | 否 | 是 | 是 |
可重複讀(Repeatable-Read) | 否 | 否 | 是 |
串行化(Serializable) | 否 | 否 | 否 |
package org.springframework.transaction.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
import org.springframework.transaction.TransactionDefinition;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
@AliasFor("transactionManager")
String value() default "";
@AliasFor("value")
String transactionManager() default "";
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.DEFAULT;
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
boolean readOnly() default false;
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
七、映射
@RequestMapping
可以用在類上和方法上,用來映射web請求到某一個類或者方法上。
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
@AliasFor("value")
String[] path() default {};
RequestMethod[] method() default {};
String[] params() default {};
String[] headers() default {};
String[] consumes() default {};
String[] produces() default {};
}
@GetMapping/@PostMapping/@PutMapping/@PatchMapping/@DeleteMapping
@GetMapping就是@RequestMapping中的RequestMethod爲GET。
其他註解類似。
package org.springframework.web.bind.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping
八、異步任務
@EnableAsync
開啓對異步任務的支持,放在啓動類上
@Async
在方法使用該註解來指明這是一個異步操作
注意:
@Async異步方法和調用異步方法的方法不能在同一個類中,@Transactional同樣,原因是@Async和@Transactional利用了動態代理機制。具體原因參考 https://blog.csdn.net/clementad/article/details/47339519。
異步方法和事務方法不能是private方法
九、元註解
元註解就是註解註解的註解0.0
@Target
描述註解的使用範圍,有下面10種,分別是
類或接口 / 成員變量 / 成員方法 / 方法參數 / 構造方法 / 局部變量 / 註解類 / 包 / 類型參數 / 使用類型的地方
package java.lang.annotation;
public enum ElementType {
/** Class, interface (including annotation type), or enum declaration */
TYPE,
/** Field declaration (includes enum constants) */
FIELD,
/** Method declaration */
METHOD,
/** Formal parameter declaration */
PARAMETER,
/** Constructor declaration */
CONSTRUCTOR,
/** Local variable declaration */
LOCAL_VARIABLE,
/** Annotation type declaration */
ANNOTATION_TYPE,
/** Package declaration */
PACKAGE,
/**
* Type parameter declaration
*
* @since 1.8
*/
TYPE_PARAMETER,
/**
* Use of a type
*
* @since 1.8
*/
TYPE_USE
}
@Retention
描述註解保留的時間範圍,有下面3種,分別是
源文件保留 / 編譯期保留(默認)/ 運行期保留
package java.lang.annotation;
public enum RetentionPolicy {
/**
* Annotations are to be discarded by the compiler.
*/
SOURCE,
/**
* Annotations are to be recorded in the class file by the compiler
* but need not be retained by the VM at run time. This is the default
* behavior.
*/
CLASS,
/**
* Annotations are to be recorded in the class file by the compiler and
* retained by the VM at run time, so they may be read reflectively.
*
* @see java.lang.reflect.AnnotatedElement
*/
RUNTIME
}
@Documented
描述在使用 javadoc 工具爲類生成幫助文檔時是否要保留其註解信息。
@Inherited
使被它修飾的註解具有繼承性(如果某個類使用了被@Inherited修飾的註解,則其子類將自動具有該註解)。