五種元注解
元注解既是注解在注解方法上的注解,有點繞口,可以簡單認為幾乎所有注解類會被這5種注解種的N種所修飾
@Target
這是用來标記目前注解的作用範圍,java.lang.annotation.ElementType,Target通過ElementType來指定注解可使用範圍的枚舉集合
取值 | 注解使用範圍 |
METHOD | 可用于方法上 |
TYPE | 可用于類或者接口上 |
ANNOTATION_TYPE | 可用于注解類型上(被@interface修飾的類型) |
CONSTRUCTOR | 可用于構造方法上 |
FIELD | 可用于域上 |
LOCAL_VARIABLE | 可用于局部變量上 |
PACKAGE | 用于記錄java檔案的package資訊,這裡比較特别 |
PARAMETER | 可用于參數上 |
這裡重點說明下:ElementType. PACKAGE。它并不是使用在一般的類中,而是用在固定的檔案package-info.java中。這裡需要強調命名一定是“package-info”。由于package-info.java并不是一個合法的類,使用eclipse建立類的方式會提示不合法,是以需要以建立檔案的方式來建立package-info.java。
例如,定義可使用範圍PACKAGE:
@Target({ElementType.PACKAGE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface AsynLog {
}
那麼,建立檔案:package-info.java,内容如下:
@AsynLog
package org.my.commons.logs.annotation;
@Retention:解釋說明注解的存活時間。
它的取值如下:
—— RetentionPolicy.SOURCE 注解隻在源碼階段保留,在編譯器進行編譯時它将被丢棄忽視。
——RetentionPolicy.CLASS 注解隻被保留到編譯進行的時候,它并不會被加載到 JVM 中。
——RetentionPolicy.RUNTIME 注解可以保留到程式運作的時候,它會被加載進入到 JVM 中,是以在程式運作時可以擷取到它們。
@Documented:能夠将注解中的元素包含到 Javadoc 中去。
@Inherited:如果一個父類被 @Inherited 注解過的注解進行注解的話,那麼如果它的子類沒有被任何注解應用的話,那麼這個子類就繼承了父類的注解。
@Repeatable:注解的值可以同時取多個。
常用注解概述:
·@Service:用于标注業務層元件;
·@Controller:用于标注控制層元件(如Struts中的action);
·@Repository:用于标注資料通路元件,即DAO元件;
·@Component:泛指元件,當元件不好歸類的時候,我們可以使用這個注解進行标注;
·@Autowired:預設按類型裝配,如果我們想使用按名稱裝配,可以結合@Qualifier注解一起使用。如下:
@[email protected]("personDaoBean")存在多個執行個體配合使用;
·@Resource:預設按名稱裝配,當找不到與名稱比對的bean才會按類型裝配;
·@PreDestory:摧毀注解,預設單例,啟動就加載;
·@Async:異步方法調用;
·@Configuration:把一個類作為一個IOC容器,它的某個方法頭上如果注冊了@Bean,就會作為這個spring容器中的Bean;
·@Scope:用于指定scope作用域的(用在類上);
·@PostConstruct:用于指定初始化方法(用在方法上);
·@PreDestory:用于指定銷毀方法(用在方法上);
·@DependsOn:定義Bean初始化及銷毀時的順序;
·@Primary:自動裝配時當出現多個Bean候選者時,被注解為@Primary的Bean将作為首選者,否則将抛出異常;
·@Lazy(true):表示延遲初始化。
2、@Scope
如上:@Scope可以指定模式,預設還是singleton,即單例模式。“prototype”表示原型,即每次都會new出一個新的出來。
3、@Service
@Service和@Controller、@Repository、@Component其實都是一樣的,當你知道這個類具體是幹什麼的就用具體的注解,如果不知道就用@Component。(概述中已叙述清楚)
另外:這裡的@Service,幹了兩件事:
a.聲明該類是一個bean,這樣才可以使用@Autowired來自動注入;
b.這個類的bean的id是類名,且首字母小寫,你也可以這樣做,@Service("這裡是你想要的id名")。
4、@[email protected](“指定bean”)配套使用
這種情況是:當出現一個接口有多個實作類時來區分使用,例如下面的AnnotationService,這個接口就有兩個實作類。
package com.annotation;
import com.annotation.service.AnnotationService;
@Component
public class QualifierResoutce {
@Autowired
@Qualifier("annotationServiceImpl2")
// @Resource(name="annotationServiceImpl2")
public AnnotationService as;
}
上面的@Component,就是不知道這個類是幹嘛的,是以就使用這個注解;
而這兩個注解的配套使用就是,自動注入這個屬性,并且走的是這個屬性(接口)的哪個實作類。
5、@Resource
上面也出現了這個注解,這個注解和@Autowired非常類似。
@Resource的裝配順序:
[email protected]後面沒有任何内容,預設通過name屬性去比對bean,找不到再按type去比對;
b.指定了name或者type則根據指定的類型去比對bean;
c.指定了name和type則根據指定的name和type去比對bean,任何一個不比對都将報錯。
@Resource和@Autowired的差別:
[email protected]預設按照byType方式進行bean比對,@Resource預設按照byName方式進行bean比對;
[email protected]是Spring的注解,@Resource是J2EE的注解,這個看一下導入注解的時候這兩個注解的包名就一清二楚了。
Spring屬于第三方的,J2EE是java自己的東西,是以,建議使用@Resource注解,以減少代碼和Spring之間的耦合。
6、@Controller
@Controller對應表現層的Bean,也就是Action,當使用這個注解以後,spring容器中就會有一個和這個注解的類名相同(首字母小寫)的action;
也可以這樣@Controller("ActionName")來指定名字;
同樣,@Repository,也是這樣的。
自定義注解
自定義注解的屬性也叫做成員變量。注解隻有成員變量,沒有方法。注解的成員變量在注解的定義中以“無形參的方法”形式來聲明,其方法名定義了該成員變量的名字,其傳回值定義了該成員變量的類型。
格式:
@元注解
public @interface 注解名{
String 屬性名() default "屬性預設值";
}
自定義一個注解:
@Target({ ElementType.PARAMETER, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AspectAonn {
/**
* 子產品
*/
public String title() default "";
}
使用這個注解
@AspectAonn(title="test")
public void dm() {
System.err.println("this service");
}