? ? ? ?Spring Boot使用過程中与倡,經(jīng)常需要和很多注解打交道距帅。也是我們常說的注解編程抖仅。所以接下來我們對Spring Boot常用注解做一個簡單的收集交煞。
一 配置類相關(guān)注解
? ? ? ?
配置類相關(guān)注解 | 解釋 |
---|---|
@SpringBootApplication | 組合注解咏窿,由@SpringBootConfiguration、@EnableAutoConfiguration素征、@ComponentScan三者組成集嵌,我們一般把該注解添加在啟動類上 |
@ComponentScan | 用于指定組件的掃描路徑和過濾規(guī)則 |
@EnableAutoConfiguration | 啟用自動配置,就是讓@SpringBootConfiguration御毅、@Configuration注解起作用 |
@SpringBootConfiguration | 標注當前類是配置類 |
@Configuration | 標注當前類是配置類 |
@Bean | 注解在方法上根欧,一般在@Configuration注解類下使用,把方法返回的對象添加到Spring IOC容器里面去端蛆,并且容器里面Bean的名字就是方法名 |
@Import | 導入類凤粗,有時沒有把某個類注入到IOC容器中,但在運用的時候需要獲取該類對應的Bean今豆,這個時候我們就可以使用@Import導入需要的Bean |
@AutoConfigureAfter | 加載指定配置的類之后再加載當前類侈沪,一般和@Configuration一起出現(xiàn) |
@AutoConfigureBefore | 加載指定配置的類之前加載當前類,一般和@Configuration一起出現(xiàn) |
@AutoConfigureOrder | 指定配置類的加載順序晚凿,一般和@Configuration一起出現(xiàn) |
1.1 @SpringBootApplication
@Target(ElementType.TYPE) // 添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration //@SpringBootConfiguration
@EnableAutoConfiguration // @EnableAutoConfiguration
@ComponentScan(excludeFilters = { // @ComponentScan
@Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM,
classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
/**
* 排除特定的自動配置類 -- @EnableAutoConfiguration里面的功能
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
Class<?>[] exclude() default {};
/**
* 排除特定的自動配置類名稱 -- @EnableAutoConfiguration里面的功能
*/
@AliasFor(annotation = EnableAutoConfiguration.class)
String[] excludeName() default {};
/**
*
* 在指定的包下掃描帶組件注解的類 -- @ComponentScan里面的功能
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
String[] scanBasePackages() default {};
/**
* 指定類亭罪,會去掃描該類所在的包下面帶有組件注解的類 -- @ComponentScan里面的功能
*/
@AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
Class<?>[] scanBasePackageClasses() default {};
}
? ? ? ?@SpringBootApplication是一個組合注解,由@SpringBootConfiguration、@EnableAutoConfiguration歼秽、@ComponentScan三個注解組成.換言之加了@SpringBootApplication注解之后就把相應的三個注解的功能都加上了应役。Springboot提供了。簡化程序的配置燥筷。@SpringBootApplication注解一般添加的啟動了上箩祥。關(guān)于@SpringBootConfiguration、@EnableAutoConfiguration肆氓、@ComponentScan我們會在下面講到袍祖。
1.2 @ComponentScan
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 可以添加在類上
@Documented
@Repeatable(ComponentScans.class)
public @interface ComponentScan {
/**
* scan對應的包路徑(可以指定多個)
*/
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
/**
* 可以指定多個類或接口的class,掃描時會 在這些指定的類和接口所屬的包進行掃面。
*/
Class<?>[] basePackageClasses() default {};
/**
* 通過BeanNameGenerator來得到bean對應的名字谢揪,進而得到對應的Class
*/
Class<? extends BeanNameGenerator> nameGenerator() default BeanNameGenerator.class;
/**
* 處理檢測到的bean的scope范圍
*/
Class<? extends ScopeMetadataResolver> scopeResolver() default AnnotationScopeMetadataResolver.class;
/**
* 是否為檢測到的組件生成代理
*/
ScopedProxyMode scopedProxy() default ScopedProxyMode.DEFAULT;
/**
* 控制符合組件檢測條件的類文件 默認是包掃描下的(包括子包) *.class
*/
String resourcePattern() default ClassPathScanningCandidateComponentProvider.DEFAULT_RESOURCE_PATTERN;
/**
* 是否對帶有@Component @Repository @Service @Controller注解的類開啟檢測,默認是開啟的
*/
boolean useDefaultFilters() default true;
/**
* 指定某些定義Filter滿足條件的組件 FilterType有5種類型如:
* ANNOTATION, 注解類型 默認
* ASSIGNABLE_TYPE,指定固定類
* ASPECTJ蕉陋, ASPECTJ類型
* REGEX,正則表達式
* CUSTOM,自定義類型
*
*/
Filter[] includeFilters() default {};
/**
* 排除某些過來器掃描到的類
*/
Filter[] excludeFilters() default {};
/**
* 掃描到的類是都開啟懶加載 捐凭,默認是不開啟的
*/
boolean lazyInit() default false;
}
? ? ? ?@ComponentScan做的事情就是告訴Spring從哪里找到Bean。@ComponentScan會默認去@SpringBootApplication注解的類所在的包及其下級包去掃描bean(就是去掃描添加了@Component凳鬓、@Service茁肠、@Repository、@Controller)缩举,然后把他們添加到Spring IOC容器里面去垦梆。但是,有的時候有些包不在這個下面仅孩,這個時候我們就需要通過@ComponentScan顯示的去指定要掃描的包名了秀又。
1.3 @EnableAutoConfiguration姐仅、@SpringBootConfiguration、@Configuration
因為@EnableAutoConfiguration、@SpringBootConfiguration洼专、@Configuration這三是一體的商佛,所以咱們把他們歸到一起來說明愁茁。
1.3.1 @EnableAutoConfiguration
@Target(ElementType.TYPE) // 組件添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class) // 幫助SpringBoot應用將所有符合條件的@Configuration配置都加載到當前SpringBoot創(chuàng)建并使用的IoC容器
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
/**
* 排除特定的自動配置類
*/
Class<?>[] exclude() default {};
/**
*
* 排除特定的自動配置類名稱
*/
String[] excludeName() default {};
}
? ? ? ?@EnableAutoConfiguration注解使自動配置生效严望。用于幫助SpringBoot應用將所有符合條件的@SpringBootConfiguration、@Configuration配置加載到當前SpringBoot IOC容器里面去温艇。換句話說因悲,想使用@SpringBootConfiguration、@Configuration就得一定得使用@EnableAutoConfiguration注解勺爱。只有@EnableAutoConfiguration配合@SpringBootConfiguration晃琳、@Configuration共同作用下,才可以幫助Spring Boot把@SpringBootConfiguration琐鲁、@Configuration修飾的類里面的Bean掃描出來,添加到Spring IOC容器里面去.
按照我們常規(guī)的Spring Boot應用卫旱。我們一般會啟動類上添加@SpringBootApplication注解。其實就已經(jīng)加上了@EnableAutoConfiguration注解围段,因為@SpringBootApplication注解包括了@EnableAutoConfiguration注解顾翼。
1.3.2 @SpringBootConfiguration、@Configuration
? ? ? ?@SpringBootConfiguration奈泪、@Configuration兩個注解是一樣的适贸。用來標記配置類。
@SpringBootConfiguration
@Target(ElementType.TYPE) // 添加在類上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
public @interface SpringBootConfiguration {
}
@Configuration
@Target(ElementType.TYPE) // 添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component // 也是一個組件
public @interface Configuration {
/**
* Configuration注解的類也是一個組件涝桅,用于顯示的指定在Spring容器里面組件的名稱拜姿。
* 如果沒有顯示指定就是類的名稱并且首字母小寫
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
? ? ? ?簡單來說就是用@SpringBootConfiguration、@Configuration標注的類是配置類冯遂,同時在該類下面一般會包含一個或多個被@Bean注解的方法蕊肥。這些方法將會被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext類進行掃描。加入到Spring IOC容器中蛤肌。并且這些Bean的名稱就是方法名壁却。
1.4 @Bean
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) // 一般添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Bean {
/**
* 顯示指定Bean對應的名字批狱,如果沒有指定則是對應的方法名字
*/
@AliasFor("name")
String[] value() default {};
/**
* 顯示指定Bean對應的名字,如果沒有指定則是對應的方法名字
*/
@AliasFor("value")
String[] name() default {};
@Deprecated
Autowire autowire() default Autowire.NO;
/**
* 用來表示當前bean是否可以被注入到其他實例中儒洛,依賴注入
*/
boolean autowireCandidate() default true;
/**
* 構(gòu)造方法執(zhí)行完之后精耐,執(zhí)行的方法
*/
String initMethod() default "";
/**
* 關(guān)閉應用程序上下文時在bean實例上調(diào)用的方法的可選名稱
*/
String destroyMethod() default AbstractBeanDefinition.INFER_METHOD;
}
? ? ? ?@Bean是一個方法級別上的注解狼速,主要用在@SpringBootConfiguration琅锻、@Configuration注解的配置類里面使用。Spring Boot會幫助把@Bean注解方法的對象添加到Spring IOC容器里面去向胡,供我們在別的地方使用恼蓬。
1.4 @Import
@Target(ElementType.TYPE) // 指明該注解是添加在類上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {
/**
* 需要import的類
*/
Class<?>[] value();
}
? ? ? ?@Import注解用于幫助把我們需要的類導入到組件類里面去,有時沒有把某個類注入到Spring IOC容器中僵芹,但在某個類使用的時候需要獲取該類對應的Bean处硬,此時就需要用到@Import注解。
1.5 控制配置類的加載順序(@AutoConfigureAfter拇派、@AutoConfigureBefore荷辕、@AutoConfigureOrder)
@AutoConfigureAfter、@AutoConfigureBefore
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE }) // 一般用于添加在類上
@Documented
public @interface AutoConfigureAfter {
/**
* Class數(shù)組對應的類加載之后在加載
*/
Class<?>[] value() default {};
/**
* 配置名稱對應的配置類加載之后在加載
*/
String[] name() default {};
}
@AutoConfigureOrder
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD, ElementType.FIELD })
@Documented
public @interface AutoConfigureOrder {
int DEFAULT_ORDER = 0;
/**
* 加載順序件豌,值越小越先加載
*/
int value() default DEFAULT_ORDER;
}
? ? ? ?@AutoConfigureAfter疮方、@AutoConfigureBefore、@AutoConfigureOrder三個注解用于控制配置類的加載順序茧彤。而且非常重要的一點是這三個注解一定要配合spring.factory文件來一起使用骡显,因為Spring只會對spring.factory文件下的配置類進行排序。所以我們需要在resources/META-INF/spring.factory文件里面寫入需要排序的這些配置類的路徑曾掂。
二 Bean(組件)相關(guān)注解
2.1 申明Bean相關(guān)的注解
? ? ? ?用于把一個類聲明為Bean(組件)惫谤。這樣Spring Boot啟動的時候(注意@ComponentScan注解的使用)就會把這些Bean掃描出來添加到IOC容器里面去。
申明Bean相關(guān)的注解 | 解釋 |
---|---|
@Component | 最普通的組件珠洗,可以被注入到Spring容器進行管理溜歪,通用注解 |
@Service | 作用于業(yè)務邏輯層的組件,只是標注該類處于業(yè)務邏輯層 |
@Repository | 作用于持久層(dao)的組件许蓖,并支持自動處理數(shù)據(jù)庫操作產(chǎn)生的異常 |
@Component蝴猪、@Service、@Repository注解屬性都是一樣的
@Target(ElementType.TYPE) //該注解一般用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
public @interface Component {
/**
* 組件對應的名字(獲取組件的時候可以通過類型獲取蛔糯,也可以通過名字獲日)
*/
String value() default "";
}
關(guān)于@Repository的作用,這里特別說明下。因為原生java操作數(shù)據(jù)庫所產(chǎn)生的異常只定義了幾種蚁飒,但是產(chǎn)生數(shù)據(jù)庫異常的原因卻有很多種动壤,這樣對于數(shù)據(jù)庫操作的報錯排查造成了一定的影響;而Spring拓展了原生的持久層異常淮逻,針對不同的產(chǎn)生原因有了更多的異常進行描述琼懊。所以阁簸,在注解了@Repository的類上如果數(shù)據(jù)庫操作中拋出了異常哼丈,就能對其進行處理醉旦,轉(zhuǎn)而拋出的是翻譯后的spring專屬數(shù)據(jù)庫異常车胡,方便我們對異常進行排查處理。
? ? ? ?關(guān)于@Component匈棘、@Service丧慈、@Repository的使用,最終只有一個目的主卫,希望咱們一看到@Repository就知道這個是數(shù)據(jù)庫Dao層的代碼逃默,一看到@Service注解就知道是業(yè)務層的代碼。
2.2 Bean屬性相關(guān)注解
? ? ? ?
Bean屬性相關(guān)注解 | 解釋 |
---|---|
@Scope | 設(shè)置Spring容器如何新建Bean實例簇搅,一般配合@Bean完域、@Component、@Service馍资、@Repository一起使用 |
@PostConstruct | 在構(gòu)造函數(shù)執(zhí)行完之后執(zhí)行 |
@PreDestory | 在Bean銷毀之前執(zhí)行 |
2.2.1 @Scope
@Target({ElementType.TYPE, ElementType.METHOD}) // 一般用來添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
/**
* Alias for {@link #scopeName}.
* @see #scopeName
*/
@AliasFor("scopeName")
String value() default "";
/**
*
* 指定要用于帶注釋的組件/ bean的作用域的名稱
* 可以設(shè)置下面四種值
* - ConfigurableBeanFactory.SCOPE_PROTOTYPE: 每次依賴注入時筒主,都會產(chǎn)生新的對象
* - ConfigurableBeanFactory.SCOPE_SINGLETON: 單例模式,在整個應用中只能創(chuàng)建一個實例
* - org.springframework.web.context.WebApplicationContext.SCOPE_REQUEST: 在一個請求中創(chuàng)建一個實例
* - org.springframework.web.context.WebApplicationContext.SCOPE_SESSION: 每次創(chuàng)建一個會話中創(chuàng)建一個實例
*/
@AliasFor("value")
String scopeName() default "";
/**
* 指定是否應將組件配置為作用域代理
* 可以設(shè)置為下面幾種值
* - ScopedProxyMode.DEFAULT:等同于ScopedProxyMode.NO
* - ScopedProxyMode.NO:(默認)不進行代理
* - ScopedProxyMode.INTERFACES:創(chuàng)建一個JDK代理模式
* - ScopedProxyMode.TARGET_CLASS:基于類的代理模式
*/
ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
? ? ??Scope字面意思是范圍鸟蟹,標志一個注入器/對象的使用范圍乌妙,很多文章說成生命周期也是可以的。比如建钥,單例模式熊经,局部單例模式等等。@Scope注解就是用來聲明一個Bean的生命周期(作用域)然低。
? ? ??@Scope實際使用的時候一般是添加在@Bean修飾的方法上的吨灭。比如如下的實例。
@Configuration
public class ZkConfiguration {
@Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON) // 只有一個實例
@Bean(initMethod = "init", destroyMethod = "stop")
public ZkClient zkClient() {
return new ZkClient();
}
}
2.2.2 @PostConstruct
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
? ? ? ?@PostConstruct用來修飾一個分靜態(tài)并且返回void的方法檩互。該方法只會在構(gòu)造函數(shù)之后執(zhí)行一次薄风。@PostConstruct一般@Component横辆、@Service、@Repository修飾的對象里面使用锌畸。
2.2.3 @PreDestory
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
? ? ? ?@PreDestroy也是用來修飾一個分靜態(tài)并且返回void的方法幻捏。該方法只會在對象函數(shù)之后執(zhí)行一次。@PreDestory和一樣@PostConstruct一般也是在@Component钝域、@Service迷捧、@Repository修飾的對象里面使用。
2.3 Bean注入相關(guān)注解
? ? ? ?注入注解就是幫助我們自動引入依賴的對象捅位。
Bean注入相關(guān)注解 | 解釋 |
---|---|
@Autowired | 先按類型注入焰雕,然后按照名稱注入,都無法找到唯一的一個實現(xiàn)類則報錯 |
@Inject | 在Spring的環(huán)境下,@Inject和@Autowired是相同的 |
@Resource | 先按名字注入郭膛,再按類型注入如捅,都無法找到唯一的一個出現(xiàn)異常 |
@Qualifier | 用于指定Bean的名字己肮,一般配合用來配合@Autowired使用 |
2.3.1 @Autowired
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
/**
* 申明當前對象是否是必須的
*/
boolean required() default true;
}
? ? ? ?@Autowired Spring提供的工具(由Spring的依賴注入工具(BeanPostProcessor、BeanFactoryPostProcessor)自動注入Bean赤拒。它可以對類成員變量航夺、方法及構(gòu)造函數(shù)進行標注始衅。 通過 @Autowired的使用來消除 set ,get方法彻亲。@Autowired先通過類型去Spring IOC容器里面查找對象宦芦,如果沒有查找到再按照Bean名稱去查找。如果無法找到唯一的Bean并且Bean是必須的則拋出異常。(可以看下@Qualifier的用法)
2.3.2 @Inject
? ? ? ?在Spring的環(huán)境下,@Inject和@Autowired是相同的啤月。
2.3.3 @Resource
@Target({TYPE, FIELD, METHOD}) // 添加在變量或者方法上
@Retention(RUNTIME)
public @interface Resource {
/**
* 資源的JNDI名稱
*/
String name() default "";
/**
* 引用指向它的資源的名稱可以使用全局JNDI名稱鏈接到任何兼容的資源
*/
String lookup() default "";
/**
* Bean對應的類型
*/
Class<?> type() default java.lang.Object.class;
/**
* 資源的兩種可能的身份驗證類型
*/
enum AuthenticationType {
CONTAINER,
APPLICATION
}
/**
* 用于此資源的身份驗證類型。
*/
AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
/**
* 指示是否可以在此組件與其他組件之間共享此資源。
*/
boolean shareable() default true;
/**
* 此資源應映射到的產(chǎn)品特定名稱
*/
String mappedName() default "";
/**
* 此資源的描述
*/
String description() default "";
}
? ? ? ?@Resource有兩個重要屬性:name、type圾亏。@Resource和@Autowired的區(qū)別在于捧杉。@Resource先通過Bean名字去容器里面查找锤悄,如果沒找到在通過類型去容器里面查找淋样。
2.3.4 @Qualifier
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
/**
* 注解對應的名字
*/
String value() default "";
}
? ? ? ?可能會有這樣一種情況垢粮,當你創(chuàng)建多個具有相同類型的 bean 時嗅虏,并且想要用一個屬性只為它們其中的一個進行裝配裹纳,在這種情況下,我們可以使用@Qualifier注釋和@Autowired注釋通過指定哪一個真正的bean將會被裝配來消除混亂弦讽。比如如下的代碼岳悟。
private ProductInfo productInfo;
@Autowired
@Qualifier(value = "productInfo")
public void setProductInfo(ProductInfo productInfo) {
this.productInfo = productInfo;
}
2.4 Bean延時加載注解(@Lazy)
@Lazy
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.PARAMETER, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Lazy {
/**
* 是否懶加載
*/
boolean value() default true;
}
? ? ? ?@Lazy:用于標識Bean是否需要延遲加載普碎,延時加載就是在第一次使用的時候才加載。@Lazy的主要作用就是用來減少Spring IOC容器啟動的加載時間录平。
2.5 Bean依賴注解(@DependsOn)
@DependsOn
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface DependsOn {
/**
* 依賴的Bean對應的名稱
*/
String[] value() default {};
}
? ? ??@DependsOn:控制Bean加載順序麻车。指定先加載@DependsOn對應的Bean。
三 讀取配置文件(.properties斗这、.yam)相關(guān)注解
? ? ? ?讀取配置文件相關(guān)的注解动猬,就是用來幫助我們獲取到配置文件.properties、.yam里面信息的。
讀取配置文件相關(guān)注解 | 解釋 |
---|---|
@EnableConfigurationProperties | 讓使用@ConfigurationProperties注解的類生效 |
@ConfigurationProperties | 讀取配置文件的信息璃哟,并自動封裝成實體類 |
@PropertySource | 指定的屬性文件(只能加載*.properties文件户矢,不能加載yaml文件)映射到對象 |
@ImportResource | 導入Spring的*.xml配置文件荠藤,讓xml配置文件里面的內(nèi)容生效 |
3.1 @EnableConfigurationProperties
@Target(ElementType.TYPE) // 添加在類上的注解
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(EnableConfigurationPropertiesImportSelector.class)
public @interface EnableConfigurationProperties {
/**
* 對應于添加了@ConfigurationProperties的類,讓他們生效
*/
Class<?>[] value() default {};
}
? ? ? ?@EnableConfigurationProperties注解的作用是讓使用@ConfigurationProperties注解的類生效。你可以通過在@EnableConfigurationProperties注解中直接簡單的列出屬性類來快捷的注冊@ConfigurationProperties bean的定義。而且@EnableConfigurationProperties我們一般添加在Applicaiton類上面。
3.2 @ConfigurationProperties
@Target({ ElementType.TYPE, ElementType.METHOD }) // 添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ConfigurationProperties {
/**
* 屬性前綴
*/
@AliasFor("prefix")
String value() default "";
@AliasFor("value")
String prefix() default "";
/**
* 是否忽視無效的字段
*/
boolean ignoreInvalidFields() default false;
/**
* 是否忽視未知字段
*/
boolean ignoreUnknownFields() default true;
}
? ? ? ?有時候有這樣子的情景,我們想把配置文件的信息,讀取并自動封裝成實體類哈雏,這樣子,這時候,我們就可以使用@ConfigurationProperties注解,它可以把同類的配置信息自動封裝成實體類。
? ? ? ?我們用一個簡單的實例來說明,比如我們在application.yml里面添加一些自定義的屬性吹零。我們就可以通過@ConfigurationProperties注解來獲取到這些屬性值
application.yml文件里面添加
# 自定義的一些屬性
user:
info:
name: tuacy
age: 27
把這些屬性映射到實體類
@ConfigurationProperties(prefix = "user.info")
public class UserInfo {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
? ? ??最后在Application類上添加@EnableConfigurationProperties(value = {UserInfo.class})。這樣就把配置文件里面的數(shù)據(jù)都映射到UserInfo類上去了,并且UserInfo類已經(jīng)添加到了Spring IOC容器里面去了厦画。
3.3 @PropertySource
@Target(ElementType.TYPE) // 該注解添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(PropertySources.class)
public @interface PropertySource {
/**
* 指示此屬性源的名稱。如果省略蒋畜,將根據(jù)底層資源的描述生成名稱
*/
String name() default "";
/**
* 指示要加載的屬性文件的資源位置
* 例如声畏,value = "classpath:product.properties"。則表示resource目錄下的product.properties文件
*/
String[] value();
/**
* 指示是否應忽略找不到屬性資源的錯誤
*/
boolean ignoreResourceNotFound() default false;
/**
* 編碼格式
* 例如姻成,"UTF-8"
*/
String encoding() default "";
/**
* 只是怎么去解析屬性對應的值插龄,比如如果想把 yyyy-mm 轉(zhuǎn)換成Date
* @see org.springframework.core.io.support.DefaultPropertySourceFactory
* @see org.springframework.core.io.support.ResourcePropertySource
*/
Class<? extends PropertySourceFactory> factory() default PropertySourceFactory.class;
}
? ? ? ?@PropertySource注解的作用是加載指定的屬性文件(配置文件),把配置文件映射到對象佣渴。只能加載*.properties文件辫狼,不能加載yaml文件。@PropertySource一般配合@Value一起使用辛润。
? ? ? ?關(guān)于@PropertySource注解使用的一個簡單的實例膨处。
resource目錄下product.properties文件內(nèi)容(配置文件)
# 自定義配置信息
ppid = 1000
mmid = 1
ccid = 10
配置文件映射到Bean
/**
* 注入resource下product.properties文件里面的信息
*/
@Configuration
@PropertySource(value = "classpath:product.properties", encoding = "utf-8")
public class ProductInfo {
@Value("${ppid}")
private int pid;
@Value("${mmid}")
private int mid;
@Value("${ccid}")
private int cid;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
}
3.4 @ImportResource
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 該注解只能添加在類上(我們一般把他添加在主配置類上)
@Documented
public @interface ImportResource {
/**
* xml配置文件對應的位置
*/
@AliasFor("locations")
String[] value() default {};
@AliasFor("value")
String[] locations() default {};
/**
*
* 處理通過屬性指定的資源時使用的實現(xiàn)
*/
Class<? extends BeanDefinitionReader> reader() default BeanDefinitionReader.class;
}
? ? ? ?導入Spring的xml配置文件见秤,讓xml配置文件里面的內(nèi)容生效。SpringBoot中編寫的Spring配置文件是不能自動識別的真椿。(相當于把Bean放到xml配置文件里面去定義了鹃答。隨著Spring Boot的使用這種方式會越來越少,因為現(xiàn)在大部分都是通過@Configuration來配置的)突硝。
四 @Value注解
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
/**
*
* 實際值表達式
* 例如测摔,{@code #{systemProperties.myProp}}.
*/
String value();
}
? ? ? ?@Value注解用于將外部的值動態(tài)注入到Bean中,大概有如下這么幾種情況:
4.1 注入普通字符串
/**
* 注入普通字符串,相當于private String normal = "normal"
*/
@Value("normal")
private String normal;
4.2 注入操作系統(tǒng)屬性
/**
* 注入操作系統(tǒng)屬性
*/
@Value("#{systemProperties['os.name']}")
private String systemPropertiesName;
4.3 注入表達式結(jié)果
/**
* 注入表達式結(jié)果,相當于 double randomNumber = java.lang.Math).random() * 100.0
*/
@Value("#{ T(java.lang.Math).random() * 100.0 }")
private double randomNumber;
4.4 注入其他Bean屬性
/**
* 注入其他Bean屬性:相當于把IOC容器里面valueInject名字對應的對象的name屬性賦值給變量
*/
@Value("#{valueInject.name}")
private String fromAnotherBean;
4.5 注入文件資源
/**
* 注入文件資源,相當于把resource目錄下valueInjectConfig.txt文件注入進來
*/
@Value("classpath:valueInjectConfig.txt")
private Resource valueInjectConfig;
4.6 注入URL資源
/**
* 注入URL資源解恰,相當于把http://www.baidu.com對應的資源注入進來
*/
@Value("http://www.baidu.com")
private Resource baiduUrl;
4.7 注入配置文件信息
? ? ? ?比如如下的例子我們加載product.properties文件里面的信息(我們也可以加載application.yml文件里面的信息锋八,加載application.yml文件信息的時候可以不加@PropertySource指定路徑)
resource目錄下product.properties文件信息
# 自定義配置信息
ppid = 1000
mmid = 1
ccid = 10
@Value注入
/**
* 注入resource下product.properties文件里面的信息
*/
@Configuration
@PropertySource(value = "classpath:product.properties", encoding = "utf-8")
public class ProductInfo {
@Value("${ppid}")
private int pid;
@Value("${mmid}")
private int mid;
@Value("${ccid}")
private int cid;
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public int getMid() {
return mid;
}
public void setMid(int mid) {
this.mid = mid;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
}
五 環(huán)境切換相關(guān)注解
? ? ? ?環(huán)境切換注解說白了就是做到不同的環(huán)境注入不同的Bean。比如常見的有開發(fā)環(huán)境和測試環(huán)境用的數(shù)據(jù)庫配置不一樣护盈。
環(huán)境切換相關(guān)注解 | 解釋 |
---|---|
@Profile | 通過設(shè)定Environment的ActiveProfiles來設(shè)定當前Bean是否要添加到Spring IOC容器里面去 |
@Conditional | 按照一定的條件進行判斷挟纱,滿足條件給添加到Spring IOC容器里面去 |
5.1 @Profiles
@Target({ElementType.TYPE, ElementType.METHOD}) // 該注解用于添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
/**
* profile對應的名字。比如生成環(huán)境有一個名字腐宋,測試環(huán)境有一個名字
*/
String[] value();
}
? ? ??@Profiles可以實現(xiàn)不同環(huán)境(開發(fā)紊服、測試、部署等)使用不同的配置胸竞。任何@Component或@Configuration都能被@Profile標記欺嗤,從而限制加載它的時機。
5.2 @Conditional
@Target({ElementType.TYPE, ElementType.METHOD}) // 常用于添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* 繼承Condition接口的Class數(shù)組
* 當所有的Class的matches方法都返回true的時候卫枝,才滿足條件
*/
Class<? extends Condition>[] value();
}
? ? ??@Conditional注解會按照一定的條件進行判斷煎饼,滿足條件給容器注冊bean。
六 條件注解
條件注解 | 解釋 |
---|---|
@ConditionalOnClass | classpath中存在該類時起效 |
@ConditionalOnMissingClass | classpath中不存在該類時起效 |
@ConditionalOnBean | Spring IOC容器中存在該類型Bean時起效 |
@ConditionalOnMissingBean | Spring IOC容器中不存在該類型Bean時起效 |
@ConditionalOnSingleCandidate | DI容器中該類型Bean只有一個或@Primary的只有一個時起效 |
@ConditionalOnExpression | SpEL表達式結(jié)果為true時 |
@ConditionalOnProperty | 參數(shù)設(shè)置或者值一致時起效 |
@ConditionalOnResource | 指定的文件存在時起效 |
@ConditionalOnJndi | 指定的JNDI存在時起效 |
@ConditionalOnJava | 指定的Java版本存在時起效 |
@ConditionalOnWebApplication | Web應用環(huán)境下起效 |
@ConditionalOnNotWebApplication | 非Web應用環(huán)境下起效 |
? ? ? ?所有的這些條件注解一般和聲明Bean的一些注解(@Bean剃盾、@Component腺占、@Service、@Repository)同時出現(xiàn)痒谴。來控制Bean是否生成衰伯。
七 切面AOP相關(guān)注解
切面AOP相關(guān)注解 | 解釋 |
---|---|
@Aspect | 聲明一個切面,只是一個標識作用 |
@PointCut | 聲明切點,在java配置類中使用@EnableAspectJAutoProxy注解開啟Spring對AspectJ代理的支持 |
@Around | 在方法執(zhí)行之前與之后執(zhí)行 |
@Before | 在方法執(zhí)行之前執(zhí)行 |
@After | 在方法執(zhí)行之后執(zhí)行 |
@AfterReturning | 方法正常退出的時候執(zhí)行 |
@AfterThrowing | 方法有異常拋出的時候執(zhí)行 |
7.1 @Aspect
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE) // 添加在方法上
public @interface Aspect {
/**
* @return the per clause expression, defaults to singleton aspect.
* Valid values are "" (singleton), "perthis(...)", etc
*/
public String value() default "";
}
? ? ? ?@Aspect注解的作用是把當前類標識為一個切面供Spring容器讀取。@Aspect注解只是一個標識作用积蔚。
7.2 @PointCut
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 添加在方法上面
public @interface Pointcut {
/**
* 切入點表達式
*/
String value() default "";
/**
* 指定命名切入點方法參數(shù)列表參數(shù)名字意鲸,
* 可以有多個用“,”分隔尽爆,這些參數(shù)將傳遞給通知方法同名的參數(shù)怎顾,
* 同時比如切入點表達式“args(param)”將匹配參數(shù)類型為命名切入點方法同名參數(shù)指定的參數(shù)類型。
*/
String argNames() default "";
}
? ? ? ?@Pointcut:Pointcut是植入Advice的觸發(fā)條件漱贱。每個Pointcut的定義包括2部分槐雾,一是表達式,二是方法簽名幅狮。方法簽名必須是public及void型募强≈昃模可以將Pointcut中的方法看作是一個被Advice引用的助記符,因為表達式不直觀擎值,因此我們可以通過方法簽名的方式為此表達式命名慌烧。因此Pointcut中的方法只需要方法簽名,而不需要在方法體內(nèi)編寫實際代碼鸠儿。
7.3 @Around
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD) // 注解用于添加在方法上
public @interface Around {
/**
* 切入點表達式屹蚊,一般配合@Pointcut一起使用
*/
String value();
/**
* 用來接收AspectJ表達式中的參數(shù)
*/
String argNames() default "";
}
? ? ? ?@Around環(huán)繞增強,方法執(zhí)行前和執(zhí)行后都會執(zhí)行。
7.4 @Before
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Before {
/**
* 切入點表達式鲫趁,一般配合@Pointcut一起使用
*/
String value();
/**
* 用來接收AspectJ表達式中的參數(shù)
*/
String argNames() default "";
}
? ? ? ?@Before方法執(zhí)行前執(zhí)行硼讽。
7.5 @After
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface After {
/**
* 切入點表達式并齐,一般配合@Pointcut一起使用
*/
String value();
/**
* 用來接收AspectJ表達式中的參數(shù)
*/
String argNames() default "";
}
? ? ? ?@After方法執(zhí)行后執(zhí)行。
7.6 @AfterReturning
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterReturning {
/**
* 切入點表達式,一般配合@Pointcut一起使用
*/
String value() default "";
/**
* 切入點表達式炉峰,一般配合@Pointcut一起使用,指定時覆蓋 "value"
*/
String pointcut() default "";
/**
* 用于綁定返回值的參數(shù)的名稱
*/
String returning() default "";
/**
* 用來接收AspectJ表達式中的參數(shù)
*/
String argNames() default "";
}
? ? ? ?@AfterReturning方法正常退出的時候執(zhí)行淘邻。
7.7 @AfterThrowing
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface AfterThrowing {
/**
* 切入點表達式,一般配合@Pointcut一起使用
*/
String value() default "";
/**
* 切入點表達式嗦随,一般配合@Pointcut一起使用,指定時覆蓋 "value"
*/
String pointcut() default "";
/**
* 用于綁定拋出異常的參數(shù)的名稱
*/
String throwing() default "";
/**
* 用來接收AspectJ表達式中的參數(shù)
*/
String argNames() default "";
}
? ? ? ?@AfterThrowing方法拋出異常的時候執(zhí)行列荔。
八 事件監(jiān)聽注解(@EventListener)
@EventListener
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) // 添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface EventListener {
/**
* 此偵聽器處理的事件類。具體可以參考ApplicationEvent的用法
*/
@AliasFor("classes")
Class<?>[] value() default {};
@AliasFor("value")
Class<?>[] classes() default {};
/**
* 用來定義所偵聽事件是否處理的前置條件枚尼,這里需要注意的是使用 Spring Expression Language (SpEL)定義條件
* condition可以實現(xiàn)更加精細的事件監(jiān)聽
*
* 比如如下的例子贴浙,監(jiān)聽CustomEvent里面messageEntity對象的code的屬性為‘oKong’的事件
* @EventListener(condition = "#customEvent.messageEntity.code == 'oKong'")
* public void handleCustomEventByCondition(CustomEvent customEvent) {
* //TODO:
* }
*/
String condition() default "";
}
? ? ? ?@EventListener修飾在方法上。用于監(jiān)聽Spring事件署恍。更加具體的用法可以參考ApplicationListener的使用崎溃。
七 異步注解
異步注解 | 解釋 |
---|---|
@EnableAsync | 開啟異步方法的支持 |
@Async | 異步方法 |
7.1 @EnableAsync
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AsyncConfigurationSelector.class)
public @interface EnableAsync {
/**
* 指示要在類或方法級別檢測的“異步”注釋類型,默認是@Async
*/
Class<? extends Annotation> annotation() default Annotation.class;
/**
* 當AdviceModemode為PROXY時盯质,選擇代理是基于接口實現(xiàn)還是cglib實現(xiàn)
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK實現(xiàn)還是AspectJ實現(xiàn)
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的順序
* 默認值是 Ordered.LOWEST_PRECEDENCE,為了在所有其他后處理器之后運行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
? ? ??@EnableAsync用于開啟異步方法的支持袁串。只有開啟了異步方法的支持才可以使用@Async概而。
7.2 @Async
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Async {
/**
*
* 指定異步操作的限定符值。
*/
String value() default "";
}
? ? ??@Async可以把某一個方法或者類下面的方法全部變成異步處理的方法囱修。
八 定時任務相關(guān)注解
? ? ? ?
定時任務相關(guān)注解 | 解釋 |
---|---|
@EnableScheduling | 在配置類上使用赎瑰,開啟計劃任務的支持 |
@Scheduled | 來申明這是一個任務,包括cron,fixDelay,fixRate等類型 |
8.1 @EnableScheduling
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Import(SchedulingConfiguration.class)
@Documented
public @interface EnableScheduling {
}
? ? ? ?@EnableScheduling注解用于開啟定時任務的支持破镰。簡單來說就是如果我們想在應用里面使用@Scheduled就需要添加@EnableScheduling注解餐曼。一般添加在主配置類上。
8.2 @Scheduled
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Repeatable(Schedules.class)
public @interface Scheduled {
/**
* cron表達式
*/
String cron() default "";
/**
* 時區(qū)
* java.util.TimeZone#ID鲜漩。cron表達式會基于該時區(qū)解析
*/
String zone() default "";
/**
* 上一次執(zhí)行完畢時間點之后多長時間再執(zhí)行
* @Scheduled(fixedDelay = 5000) //上一次執(zhí)行完畢時間點之后5秒再執(zhí)行
*/
long fixedDelay() default -1;
/**
* 與fixedDelay意思相同源譬,只是使用字符串的形式。唯一不同的是支持占位符
* @Scheduled(fixedDelayString = "5000") //上一次執(zhí)行完畢時間點之后5秒再執(zhí)行
*/
String fixedDelayString() default "";
/**
* 上一次開始執(zhí)行時間點之后多長時間再執(zhí)行
* @Scheduled(fixedRate = 5000) //上一次開始執(zhí)行時間點之后5秒再執(zhí)行
*/
long fixedRate() default -1;
/**
* 與fixedRate意思相同孕似,只是使用字符串的形式
*/
String fixedRateString() default "";
/**
* 第一次延遲多長時間后再執(zhí)行
*/
long initialDelay() default -1;
/**
* 與initialDelay意思相同踩娘,只是使用字符串的形式
*/
String initialDelayString() default "";
}
? ? ? ?@Scheduled用于定義一個定時任務。Spring會幫我們?nèi)ソ馕鲞@個定時任務喉祭,并且按照我們設(shè)置的時間去執(zhí)行這個任務养渴。
九 事務相關(guān)注解
事務相關(guān)注解 | 解釋 |
---|---|
@EnableTransactionManagement | 開啟注解式事務的支持 |
@Transactional | 控制事務注解 |
9.1 @EnableTransactionManagement
@Target(ElementType.TYPE) // 該注解用于添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
/**
* 當AdviceModemode為PROXY時,選擇代理是基于接口實現(xiàn)還是cglib實現(xiàn)
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK實現(xiàn)還是AspectJ實現(xiàn)
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的順序
* 默認值是 Ordered.LOWEST_PRECEDENCE,為了在所有其他后處理器之后運行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
? ? ? ?@EnableTransactionManagement用于開啟事務的支持泛烙,我們一般在主配置類上添加該注解厚脉。
9.2 @Transactional
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Transactional {
/**
* 當在配置文件中有多個 TransactionManager , 可以用該屬性指定選擇哪個事務管理器。
*/
@AliasFor("transactionManager")
String value() default "";
/**
* 當在配置文件中有多個 TransactionManager , 可以用該屬性指定選擇哪個事務管理器胶惰。
*/
@AliasFor("value")
String transactionManager() default "";
/**
* 事務的傳播行為,默認值為 REQUIRED
* 默認 Propagation.REQUIRED
*/
Propagation propagation() default Propagation.REQUIRED;
/**
* 事務的隔離度霞溪,默認值采用 DEFAULT
*/
Isolation isolation() default Isolation.DEFAULT;
/**
* 事務的超時時間孵滞,默認值為-1。如果超過該時間限制但事務還沒有完成鸯匹,則自動回滾事務
*/
int timeout() default TransactionDefinition.TIMEOUT_DEFAULT;
/**
* 指定事務是否為只讀事務坊饶,默認值為 false;為了忽略那些不需要事務的方法殴蓬,比如讀取數(shù)據(jù)匿级,可以設(shè)置 read-only 為 true。
*/
boolean readOnly() default false;
/**
* 用于指定能夠觸發(fā)事務回滾的異常類型染厅,
*/
Class<? extends Throwable>[] rollbackFor() default {};
String[] rollbackForClassName() default {};
/**
* 拋出 no-rollback-for 指定的異常類型痘绎,不回滾事務。
*/
Class<? extends Throwable>[] noRollbackFor() default {};
String[] noRollbackForClassName() default {};
}
? ? ? ?@Transactional注解我們一般添加在Dao層的方法上面肖粮。當數(shù)據(jù)庫操作異常的時候回滾孤页。
十 緩存相關(guān)注解
緩存相關(guān)注解 | 解釋 |
---|---|
@EnableCaching | 開啟緩存注解的支持 |
@CacheConfig | 用于統(tǒng)一制定一些配置參數(shù),這樣在其他緩存注解里面就不用重復指定 |
@Cacheable | 如果之前已經(jīng)有緩存數(shù)據(jù)值直接返回緩存數(shù)據(jù)涩馆,否則執(zhí)行方法罐栈,緩存方法的返回結(jié)果 |
@CachePut | 能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存确丢,和 @Cacheable 不同的是极谊,它每次都會觸發(fā)真實方法的調(diào)用 |
@CacheEvict | 能夠根據(jù)一定的條件對緩存進行清空 |
@Caching | 組合多個Cache注解的使用 |
10.1 @EnableCaching
@Target(ElementType.TYPE) // 該注解一般用于添加類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(CachingConfigurationSelector.class)
public @interface EnableCaching {
/**
* 當AdviceModemode為PROXY時,選擇代理是基于接口實現(xiàn)還是cglib實現(xiàn)
*/
boolean proxyTargetClass() default false;
/**
* 代理方式是由JDK實現(xiàn)還是AspectJ實現(xiàn)
*/
AdviceMode mode() default AdviceMode.PROXY;
/**
*
* 指示AsyncAnnotationBeanPostProcessors的順序
* 默認值是 Ordered.LOWEST_PRECEDENCE,為了在所有其他后處理器之后運行
*/
int order() default Ordered.LOWEST_PRECEDENCE;
}
? ? ? ?@EnableCaching注解用于開啟緩存的支持稠项,只有開啟了緩存的支持,才有后續(xù)的@Cacheable鲜结、@Caching展运、@CacheEvict、@CachePut轻腺、@CacheConfig的使用乐疆。
10.2 @CacheConfig
@Target(ElementType.TYPE) // 該注解常用于添加在類上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheConfig {
/**
* 緩存的名稱,必須至少指定一個贬养,我們可以簡單的認為是命名空間挤土。我們一般用項目的名字
*/
String[] cacheNames() default {};
/**
* key生成器,可以實現(xiàn) org.springframework.cache.interceptor.KeyGenerator接口误算,來規(guī)定想要保存的key的格式
* 設(shè)置自定義的key生成器實現(xiàn)類對應Bean的名字
*/
String keyGenerator() default "";
/**
* 緩存管理器仰美,我們可以實現(xiàn)CacheManager接口來實現(xiàn)緩存管理器
* 指定自定義的緩存管理器對應的Bean名稱
*/
String cacheManager() default "";
/**
* Cache解析器,用于根據(jù)實際情況來動態(tài)解析使用哪個Cache儿礼,實現(xiàn)CacheResolver接口
* 指定自定義的Cache解析器對應的Bean名稱
*/
String cacheResolver() default "";
}
? ? ??當我們需要緩存的地方越來越多咖杂,這個時候我們可以使用@CacheConfig注解來統(tǒng)一制定一些參數(shù)。這樣在@Cacheable蚊夫、@CachePut等這些注解上就可以不用重復去填這些參數(shù)了诉字。
10.3 @Cacheable
@Target({ElementType.METHOD, ElementType.TYPE}) // 該注解用于添加在方法或者類上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Cacheable {
/**
* 緩存的名稱,必須至少指定一個,緩存的名稱知纷,必須至少指定一個壤圃,我們可以簡單的認為是命名空間。我們一般用項目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 緩存的key
*/
String key() default "";
/**
* key生成器琅轧,可以實現(xiàn) org.springframework.cache.interceptor.KeyGenerator接口伍绳,來規(guī)定想要保存的key的格式
* 設(shè)置自定義的key生成器實現(xiàn)類對應Bean的名字
*/
String keyGenerator() default "";
/**
* 緩存管理器,我們可以實現(xiàn)CacheManager接口來實現(xiàn)緩存管理器
* 指定自定義的緩存管理器對應的Bean名稱
*/
String cacheManager() default "";
/**
* Cache解析器乍桂,用于根據(jù)實際情況來動態(tài)解析使用哪個Cache冲杀,實現(xiàn)CacheResolver接口
* 指定自定義的Cache解析器對應的Bean名稱
*/
String cacheResolver() default "";
/**
* 緩存的條件
*/
String condition() default "";
/**
* 否定緩存。當條件結(jié)果為TRUE時睹酌,就不會緩存
* @Cacheable(value=”testcache”,unless=”#userName.length()>2”)
*/
String unless() default "";
/**
* 是否使用異步模式
*/
boolean sync() default false;
}
? ? ? ?@Cacheable注解會先查詢是否已經(jīng)有緩存权谁,有會使用緩存,沒有則會執(zhí)行方法并緩存憋沿。
10.4 @CachePut
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CachePut {
/**
* 緩存的名稱闯传,必須至少指定一個,我們可以簡單的認為是命名空間。我們一般用項目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 緩存的key
*/
String key() default "";
/**
* key生成器甥绿,可以實現(xiàn) org.springframework.cache.interceptor.KeyGenerator接口字币,來規(guī)定想要保存的key的格式
* 設(shè)置自定義的key生成器實現(xiàn)類對應Bean的名字
*/
String keyGenerator() default "";
/**
* 緩存管理器,我們可以實現(xiàn)CacheManager接口來實現(xiàn)緩存管理器
* 指定自定義的緩存管理器對應的Bean名稱
*/
String cacheManager() default "";
/**
* Cache解析器共缕,用于根據(jù)實際情況來動態(tài)解析使用哪個Cache洗出,實現(xiàn)CacheResolver接口
* 指定自定義的Cache解析器對應的Bean名稱
*/
String cacheResolver() default "";
/**
* 緩存的條件
*/
String condition() default "";
/**
* 否定緩存。當條件結(jié)果為TRUE時图谷,就不會緩存
* @Cacheable(value=”testcache”,unless=”#userName.length()>2”)
*/
String unless() default "";
}
? ? ??@CachePut注解的作用主要針對方法配置翩活,能夠根據(jù)方法的請求參數(shù)對其結(jié)果進行緩存,和@Cacheable不同的是便贵,它每次都會觸發(fā)真實方法的調(diào)用 菠镇。簡單來說就是用戶更新緩存數(shù)據(jù)。但需要注意的是該注解的value 和 key 必須與要更新的緩存相同承璃,也就是與@Cacheable相同利耍。
10.5 @CacheEvict
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface CacheEvict {
/**
* 緩存的名稱,必須至少指定一個盔粹,我們可以簡單的認為是命名空間隘梨。我們一般用項目的名字
*/
@AliasFor("cacheNames")
String[] value() default {};
@AliasFor("value")
String[] cacheNames() default {};
/**
* 緩存的key
*/
String key() default "";
/**
* key生成器,可以實現(xiàn) org.springframework.cache.interceptor.KeyGenerator接口舷嗡,來規(guī)定想要保存的key的格式
* 設(shè)置自定義的key生成器實現(xiàn)類對應Bean的名字
*/
String keyGenerator() default "";
/**
* 緩存管理器轴猎,我們可以實現(xiàn)CacheManager接口來實現(xiàn)緩存管理器
* 指定自定義的緩存管理器對應的Bean名稱
*/
String cacheManager() default "";
/**
* Cache解析器,用于根據(jù)實際情況來動態(tài)解析使用哪個Cache进萄,實現(xiàn)CacheResolver接口
* 指定自定義的Cache解析器對應的Bean名稱
*/
String cacheResolver() default "";
/**
* 緩存的條件
*/
String condition() default "";
/**
* 是否清空所有緩存內(nèi)容捻脖,缺省為 false,如果指定為 true中鼠,則方法調(diào)用后將立即清空所有緩存
*/
boolean allEntries() default false;
/**
* 是否在方法執(zhí)行前就清空郎仆,缺省為 false,
* 如果指定為 true兜蠕,則在方法還沒有執(zhí)行的時候就清空緩存,缺省情況下抛寝,如果方法執(zhí)行拋出異常熊杨,則不會清空緩存
*/
boolean beforeInvocation() default false;
}
? ? ??@CacheEvict能夠根據(jù)一定的條件對緩存進行清空。
10.6 @Caching
@Target({ElementType.METHOD, ElementType.TYPE}) // 添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Caching {
Cacheable[] cacheable() default {};
CachePut[] put() default {};
CacheEvict[] evict() default {};
}
? ? ??@Caching用于組合多個Cache注解的使用盗舰。相當于在一個方法上面添加多個注解晶府。
關(guān)于Spring Boot緩存這部分的內(nèi)容,咱們可以試著去整合redis或者ehcache來使用钻趋。
十一 Spring MVC相關(guān)注解
? ? ? ?
Spring MVC相關(guān)注解 | 解釋 |
---|---|
@Controller | 聲明該類為SpringMVC中的Controller,用來處理http請求 |
@RestController | 組合注解川陆,@Controller + @ResponseBody.意味著,該Controller的所有方法都默認加上了@ResponseBody |
@RequestMapping | 把htt請求映射到方法上去 |
@PathVariable | 用于接收路徑參數(shù)蛮位,比如@RequestMapping(“/hello/{name}”)申明的路徑较沪,將注解放在參數(shù)中前鳞绕,即可獲取該值,通常作為Restful的接口實現(xiàn)方法 |
@RequestParam | 將請求參數(shù)綁定至方法參數(shù) |
@RequestBody | 用于讀取Request請求的body部分數(shù)據(jù) |
@ResponseBody | 將Controller的方法返回的對象尸曼,通過適當?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后们何,寫入到Response對象的body數(shù)據(jù)區(qū) |
@ModelAttribute | 主要作用是綁定request或是form參數(shù)到模型(Model) |
@InitBinder | 用來設(shè)置WebDataBinder,WebDataBinder用來自動綁定前臺請求參數(shù)到Model中 |
@ExceptionHandler | 用于全局處理控制器里的異常 |
@ControllerAdvice | 通過該注解控轿,我們可以將對于控制器的全局配置放置在同一個位置,和@Controller對應 |
@RestControllerAdvice | 同上和@RestController對應 |
11.1 @Controller
@Target({ElementType.TYPE}) // 該注解用于添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
/**
* 用于顯示指定組件的名稱
* @Contorller 修飾的類對應的對象也是一個Bean,是一個注解冤竹,
*/
@AliasFor(annotation = Component.class)
String value() default "";
}
? ? ? ?@Controller的作用很簡單,就是表示添加了該注解的類是負責處理由DispatcherServlet 分發(fā)的http請求的茬射。
11.2 @RestController
? ? ? ?@RestController是一個組合注解鹦蠕,@Controller+@ResponseBody。關(guān)于@ResponseBody的解釋在抛,我們會在下文講到钟病。
11.3 @RequestMapping
@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 {};
/**
* 指定請求的method類型档悠, GET、POST望浩、PUT辖所、DELETE等
*/
RequestMethod[] method() default {};
/**
* 指定request中必須包含某些參數(shù)值,才讓該方法處理
* 1. param1: 表示請求必須包含名為param1的請求參數(shù)
* 2. !param1: 表示請求不能包含名為param1的請求參數(shù)
* 3. param1!=value1: 表示請求包含名為param1的請求參數(shù)磨德,但其值不能為 value1
* 4. {"param1=value1", "param2"}: 請求必須包含名為 param1和param2的兩個請求參數(shù)缘回,且 param1參數(shù)的值必須為 value1
*/
String[] params() default {};
/**
* 指定request中必須包含某些指定的header值,才能讓該方法處理請求典挑。
* 比如, @RequestMapping(value = "/something", headers = "content-type=text/*")
* 將會匹配所有請求里面包含 Content-Type of "text/html", "text/plain", etc.
*/
String[] headers() default {};
/**
* 指定處理請求的提交內(nèi)容類型(Content-Type),例如application/json, text/html
* Examples:
* consumes = "text/plain"
* consumes = {"text/plain", "application/*"}
*/
String[] consumes() default {};
/**
* 指定返回的內(nèi)容類型您觉,僅當request請求頭中的(Accept)類型中包含該指定類型才返回
* Examples:
* <pre class="code">
* produces = "text/plain"
* produces = {"text/plain", "application/*"}
* produces = MediaType.APPLICATION_JSON_UTF8_VALUE
* </pre>
*/
String[] produces() default {};
}
? ? ? ?@RequestMapping是一個用來處理請求地址映射的注解拙寡。該注解可用于類或方法上,用于類上琳水,表示類中的所有響應請求的方法都是以該地址作為父路徑肆糕。@RequestMapping最終的目的就是把http對應的請求映射到對應的方法上。
11.3 @PathVariable
@Target(ElementType.PARAMETER) // 該注解用于添加在參數(shù)上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface PathVariable {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* 要綁定的路徑變量的名稱
*/
@AliasFor("value")
String name() default "";
/**
* 該屬性是否是必須的在孝,如果設(shè)置成必須的诚啃,但是路徑里面沒有傳遞該變量過來就拋出異常
*/
boolean required() default true;
}
? ? ? ?@PathVariable注解用于從url中獲取數(shù)據(jù)。
11.4 @RequestParam
@Target(ElementType.PARAMETER) // 該注解只能加載參數(shù)上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
/**
* 請求參數(shù)名
*/
@AliasFor("name")
String value() default "";
@AliasFor("value")
String name() default "";
/**
* 是否為必須參數(shù)
*/
boolean required() default true;
/**
* 默認值私沮,沒有匹配到參數(shù)情況下的默認值
*/
String defaultValue() default ValueConstants.DEFAULT_NONE;
}
? ? ? ?@RequestParam用于將請求參數(shù)綁定至方法參數(shù)始赎。
11.5 @RequestBody
@Target(ElementType.PARAMETER) // 該注解用于添加在參數(shù)上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestBody {
/**
* 該參數(shù)是否是必須的(是否非空)
*/
boolean required() default true;
}
? ? ? ?該注解用于讀取Request請求的body部分數(shù)據(jù),使用系統(tǒng)默認配置的HttpMessageConverter進行解析,然后把相應的數(shù)據(jù)綁定到要返回的對象上造垛。簡單來說就是把Request請求對應的body數(shù)據(jù)映射成參數(shù)里面的對象魔招。
11.6 @ResponseBody
@Target({ElementType.TYPE, ElementType.METHOD}) // 該注解用于添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ResponseBody {
}
? ? ? ?該注解用于將Controller的方法返回的對象,通過適當?shù)腍ttpMessageConverter轉(zhuǎn)換為指定格式后筋搏,寫入到Response對象的body數(shù)據(jù)區(qū)仆百。
11.7 @ModelAttribute
@Target({ElementType.PARAMETER, ElementType.METHOD}) // 該注解用于添加在類或者方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ModelAttribute {
/**
* Alias for {@link #name}.
*/
@AliasFor("name")
String value() default "";
/**
* 要綁定的model屬性的名稱
*/
@AliasFor("value")
String name() default "";
/**
*
* 允許直接在ModelAttribute方法參數(shù)或從ModelAttribute方法返回的屬性上聲明數(shù)據(jù)綁定,這兩種方法都會阻止該屬性的數(shù)據(jù)綁定奔脐。
*/
boolean binding() default true;
}
? ? ? ?@ModelAttribute注解的主要作用是綁定request或是form參數(shù)到模型(Model)對象俄周。可以使用保存在request或session中的對象來組裝模型對象髓迎。注意峦朗,被@ModelAttribute注解的方法會在controller方法(@RequestMapping注解的)之前執(zhí)行。因為模型對象要先于controller方法之前創(chuàng)建排龄。
11.7.1 @ModelAttribute添加在方法上
? ? ? ?@ModelAttribute注解在方法上說明方法的作用是用于添加一個或多個屬性到Model上波势。被@ModelAttribute注釋的方法會在此Controller每個方法執(zhí)行前被執(zhí)行。因此對于一個Controller映射多個URL的用法來說橄维,要謹慎使用尺铣。
11.7.1.1 @ModelAttribute添加在沒有返回值的方法上
? ? ? ?@ModelAttribute添加的方法沒有返回值,一般這個時候我們需要自己去往Model里面添加數(shù)據(jù)了争舞,要不然沒啥意義凛忿。Model 就相當于每次請求的一個背包,我們可以往背包里面放東西竞川。
/**
* Model: 就相當于每次請求的一個背包店溢,我們可以往背包里面放東西
*/
@ModelAttribute
public void postVoidModelAttribute(@RequestParam String abc, Model model) {
// 往model里面添加一個屬性
model.addAttribute("userId0", abc);
}
11.7.1.2 @ModelAttribute添加在有返回值的方法上
? ? ? ?@ModelAttribute添加在有返回值的方法上,會自動將該返回值放到Model里面去委乌。
其實咱們這里的兩個例子是等效的床牧,都是把@RequestParam對應的值放到Model里面去了。
/**
* Model: 就相當于每次請求的一個背包遭贸,我們可以往背包里面放東西
* @ModelAttribute 添加在有返回值的放的方法上戈咳,會把返回值放到Model里面去
*/
@ModelAttribute(value = "userId1")
public String postReturnModelAttribute(@RequestParam String abc) {
return abc;
}
11.7.2 @ModelAttribute添加在參數(shù)上
? ? ? ?@ModelAttribute添加在參數(shù)上的時候用于從Model里面獲取數(shù)據(jù)。上面我們已經(jīng)通過把@ModelAttribute添加在方法上往Model里面添加了數(shù)據(jù)了壕吹,是時候取出來了著蛙。
/**
* Model: 就相當于每次請求的一個背包,我們可以往背包里面放東西
* 會在其他添加了@RequestMapping的方法之前執(zhí)行
*/
@ModelAttribute
public void postVoidModelAttribute(@RequestParam String abc, Model model) {
// 往model里面添加一個屬性
model.addAttribute("userId0", abc);
}
/**
* Model: 就相當于每次請求的一個背包算利,我們可以往背包里面放東西
* @ModelAttribute 添加在有返回值的放的方法上,會把返回值放到Model里面去
* 會在其他添加了@RequestMapping的方法之前執(zhí)行
*/
@ModelAttribute(value = "userId1")
public String postReturnModelAttribute(@RequestParam String abc) {
return abc;
}
/**
* 上面我們已經(jīng)通過把@ModelAttribute添加在方法上往Model里面去了泳姐,這個時候我們可以通過把@ModelAttribute添加在參數(shù)上獲取Model里面的值
*/
@RequestMapping(value = "/text0")
public String test0(@RequestParam String abc, @ModelAttribute("userId0") String userId) {
System.out.println(userId);
return "helloWorld";
}
/**
* 其實我們也可以直接拿到Model
*/
@RequestMapping(value = "/text1")
public String helloWorld(@RequestParam String abc, Model model) {
Map<String, Object> mapList = model.asMap();
return "helloWorld";
}
11.8 @InitBinder
@Target({ElementType.METHOD}) // 該注解只能添加在方法上
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface InitBinder {
/**
* value,作用是限制對哪些 @RequestMapping 方法起作用,
* 具體篩選條件就是通過@RequestMapping方法入?yún)砗Y選效拭,
* 默認不寫就代表對所有@RequestMapping的方法起作用。
*/
String[] value() default {};
}
? ? ? ?@InitBinder:用于給Binder做初始化,被@InitBinder注解的方法可以對WebDataBinder初始化缎患。WebDataBinder是用于表單到方法的數(shù)據(jù)綁定的慕的。只在添加了@InitBinder注解方法所在的控制器(Controller)里面有效。@InitBinder對應的方法在Controller的請求執(zhí)行映射的方法之前被執(zhí)行挤渔。同時添加了@InitBinder注解的方法返回值必須為null肮街。
? ? ? ?我們用一個具體的實例來說明@InitBinder的用法,可能有這么個場景判导,關(guān)于時間部分我們調(diào)用接口的時候傳遞的是 “2019-09-05” 的格式嫉父,但是我們后天需要Date的格式。這個時候@InitBinder就派上大用場了呀眼刃,我們可以通過@InitBinder配合WebDataBinder的使用幫我們把 “2019-09-05” 轉(zhuǎn)換成Date绕辖。
@RestController
@RequestMapping(path = "/initBinder")
public class InitBinderController {
/**
* 對當前控制器的所有請求都有效
* 前臺傳遞過來的String類型時間,通過下面的初始化綁定擂红,轉(zhuǎn)換成Date類型
*/
@InitBinder
public void initBinder(WebDataBinder binder) {
// 我們前臺傳過來的time字段對應的值可能是“2019-05-06”這樣的仪际,我們可以在這里把他們轉(zhuǎn)換成Date類型的
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd"), true));
}
@RequestMapping(value = "/test", method = RequestMethod.POST)
public String helloWorld(@RequestBody InitBinderTestVo vo) {
System.out.println(vo.getTime());
return "success";
}
}
11.9 @ExceptionHandler
@Target(ElementType.METHOD) // 標記該注解是添加在方法上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ExceptionHandler {
/**
* 當產(chǎn)生了哪些異常,就執(zhí)行當前注解添加的方法
*/
Class<? extends Throwable>[] value() default {};
}
? ? ? ?@ExceptionHandler用于全局處理控制器里的異常
11.10 @ControllerAdvice昵骤、@RestControllerAdvice
@Target(ElementType.TYPE) // 該注解是添加在類上的
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface ControllerAdvice {
/**
* 指定包下的控制器(Controller)
*/
@AliasFor("basePackages")
String[] value() default {};
@AliasFor("value")
String[] basePackages() default {};
/**
* 指定類所在的包和子包里面的控制器(Controller)
*/
Class<?>[] basePackageClasses() default {};
/**
* 直接給定控制器對應的class
*/
Class<?>[] assignableTypes() default {};
/**
* 添加了指定注解的控制器(Controller)
*/
Class<? extends Annotation>[] annotations() default {};
}
? ? ? ?@ControllerAdvice(@RestControllerAdvice)树碱,Controller增強器”淝兀可以將對于控制器的全局配置(@ExceptionHandler成榜、@InitBinder、@ModelAttribute)放在同一個位置(放到添加了@ControllerAdvice類中去實現(xiàn))伴栓。所有有@ControllerAdvice出現(xiàn)的地方的類的方法里面肯定被@ExceptionHandler伦连、@InitBinder、@ModelAttribute當中的一個修飾钳垮。
? ? ? ?關(guān)于Spring Boot注解的簡單介紹就這么寫,希望能幫助到大家.