ノートやAOPを得るために、春のカスタム注釈(アノテーション)[ターン]

まずは、カスタムアノテーションを紹介しましょう。

開発中に、我々はインターフェイスを実装し、時には@SuppressWarningsを書くように求め、@Overrideがあるでしょう。実際には、これは、Java固有の機能、注釈です。

注解就是某种注解类型的一种实例,我们可以把它用在某个类上进行标注。下面这张图解释注解都是什么?

画像

注釈は、大きく3つに分け図で見ることができる:メタ注釈、注釈タグ、一般的な注意事項。

この1は、他の私たちは、主にそれは我々が構文定義、標準のメタデータ注釈および注釈を理解する必要がある前に、あなた自身のノートを定義する方法について話ここにある、導入されません。
メタアノテーションの役割は、他の注釈ノートに責任があります。Java5.0規格は、指定された注釈の他の種類を提供するために使用される4つのメタ注釈型を定義します。Java5.0はメタアノテーションを定義しました。

1.ターゲット@、
2.リテンション@、
文書化@ 3、
4. @継承

@ターゲット
注釈@Targetは、修正目標範囲を示す:注釈はパッケージ、型(クラス、インタフェース、列挙、注釈型)、メンバーの種類(メソッド、コンストラクタ、メンバ変数列挙値)、及びメソッドのパラメータのために使用することができますローカル変数(例えば、可変ループ、キャッチパラメータ)。注釈型宣言でターゲットを使用することは、ターゲットを変更することをより明確にすることができます。
処置:注釈の使用を記載するために使用される(すなわち:注釈が記載されているが、任意の場所で使用されてもよいです)
値(のElementType)は、次のとおりです。
  1. CONSTRUCTOR:コンストラクタを記述するために使用されます
  2. FIELD:のための記述
  3. LOCAL_VARIABLE:記述するために使用されるローカル変数
  4. METHOD:について記載された方法
  5. パッケージ:パッケージには、記述するために使用しました
  6. PARAMETER:記述するために使用されるパラメータ
  7. TYPE:クラス、(注釈のタイプを含む)インターフェース、または列挙宣言を記述するために使用
@保持
@Retentionは注釈を予約された時間の長さを定義します。いくつかの注釈がソースコード内でのみ表示され、コンパイラは破棄され、他はクラスファイルをコンパイルして、仮想かもしれクラスファイルに注釈をコンパイルクラスが読み込まれたときに他の人がロードされる一方で、マシンは(注記があるためアノテーションクラスの使用、クラスの実装には影響しないと分離されている)、無視されます。このメタ注釈注釈を使用すると、「ライフサイクル」を制限することができます
役割:どのようなレベルでの注釈情報を保存する必要性を表明し、それはノートのライフサイクルを記述するために使用される(例:注釈がどの程度効果的に説明されています)
値(RetentionPoicy)は、次のとおりです。
  1. SOURCE:ソースファイル内の有効な(すなわち、ソースファイル保存)
  2. CLASS:有効なクラスファイル(つまりクラスを保有)
  3. RUNTIME:効果的な(すなわち、予約実行時)、実行時に
 @Documented
パブリックAPIプログラムのメンバーがマークされているようであるべき注釈の他のタイプを記述するために使用@Documented、そのようなJavadocドキュメントなどのツールとなります。マーカー注釈、ないメンバーがある文書化されました。
 @継承されました
@Inheritedメタ注釈がマーカー注釈で、@継承は、インデックス付きの特定のタイプが継承されて説明します。修飾@Inherited注釈型を用いたものをクラスに使用される場合、このアノテーションは、このクラスのサブクラスで使用されています。
注意:@Inherited注釈型がクラスのサブクラスの継承をオフにマークされています。クラスは、それはインターフェースの継承アノテーションを実装するメソッドをオーバーロードから注釈メソッドを継承しません。
注釈の@Inherited注釈型注釈が保持RetentionPolicy.RUNTIMEある場合は、反映APIは、この継承を強化します。私たちは、注釈の@Inherited注釈タイプを照会するjava.lang.reflectのを使用している場合は、コードのチェックを反映して作業を開始します:あなたが指定された注釈の種類を見つけるまで、クラスとその親クラスを確認し発見された、またはトップクラスの継承構造に到達します。

カスタム注釈

@interfaceは、コンパイラによって自動的にカスタムに自動的java.lang.annotation.Annotationインタフェース継承された注釈、完全に他の詳細を使用します。ノートを定義する場合、注釈は、インターフェースを継承するか、他のことはできません。@interfaceアノテーションを宣言するために使用される方法の各々は、実際の設定パラメータを宣言しています。メソッドの名前は、戻り型が型パラメータ(戻り値型は、基本的なタイプ、クラス、文字列、列挙型であってもよい)であり、パラメータの名前です。あなたは、デフォルトでは、パラメータのデフォルト値を宣言することができます。
カスタム注釈形式:
公共@interface注釈定義体名} {

   サポート可能なデータ型注釈パラメータ:
   1.すべての基本データ型(int型、float型、ブール、バイト、ダブル、文字、ロング、ショート)
   2.文字列型
   3.クラスタイプ
   4.列挙型
   5.注釈型
   6以上すべてのタイプのアレイ
  
  のパラメータを内部注釈型方法を設定:
  、唯一そのような文字列値として、これら2つの変更、()へのパブリックまたは既定(デフォルト)アクセスの最初;ここで、デフォルトの方式が設定されているdefaulタイプ;.
  最初第二に、基本的なパラメータのメンバーは、タイプがバイト、ショート、CHAR、INT、使用することができます長い、フロート、ダブル、ブール8つの基本データ型と文字列、列挙型、クラス、注釈および他のデータ型と同様に、この配列のいくつかのタイプを。例えば、文字列値は、();ここでは、パラメータ文字列のメンバーであり、
  第三の、パラメータの一方のみメンバー場合は、パラメータ名「値」を設定するのが最善である、例括弧を添加した後、次の例では、FruitNameのみつのパラメータ部材ノート。


使用例:

CacheRedis.java

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface CacheRedis { String key(); int expireTime() default 600; }

CacheService.java

import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; @Aspect @Component public class CacheService { Logger logger = LoggerFactory.getLogger(CacheService.class); @Pointcut(value = "@annotation(com.meizu.bro.service.test.CacheRedis)") public void pointCut(){} @Before(value = "pointCut() && @annotation(cacheRedis)") public void before(CacheRedis cacheRedis) { logger.info("the result of this method will be cached."); } @AfterReturning(value = "pointCut() && @annotation(cacheRedis)",returning = "result") public void after(CacheRedis cacheRedis,Object result) { String key = cacheRedis.key(); int expireTime = cacheRedis.expireTime(); //do something... logger.info("-----redis-----[key = " + key + "]"+"[expireTime = " + expireTime + "]"); logger.info("the result of this method is" + result + ",and has been cached."); } //@Around("pointCut() && @annotation(cacheRedis)") //public Object setCache(ProceedingJoinPoint joinPoint,CacheRedis cacheRedis) { // Object result = 1; // // Method method = getMethod(joinPoint);//自定义注解类 // //CacheRedis cacheRedis = method.getAnnotation(CacheRedis.class);//获取key值 // String key = cacheRedis.key(); // int expireTime = cacheRedis.expireTime(); // //获取方法的返回类型,让缓存可以返回正确的类型 // Class returnType =((MethodSignature)joinPoint.getSignature()).getReturnType(); // // logger.info("[key = " + key + "]"+"[expireTime = " + expireTime + "]"); // // return result; //} // //private Method getMethod(ProceedingJoinPoint joinPoint) { // //获取参数的类型 // Method method = null; // try { // Signature signature = joinPoint.getSignature(); // MethodSignature msig = null; // if (!(signature instanceof MethodSignature)) { // throw new IllegalArgumentException("该注解只能用于方法"); // } // msig = (MethodSignature) signature; // method = joinPoint.getTarget().getClass().getMethod(msig.getName(), msig.getParameterTypes()); // } catch (NoSuchMethodException e) { // logger.error("annotation no sucheMehtod", e); // } catch (SecurityException e) { // logger.error("annotation SecurityException", e); // } // return method; //} } 

試験インタフェースTestController.java

@Controller
public class TestController { @Autowired private TestService testService; @RequestMapping(value = "/test") public ModelAndView myTest() { int test = testService.test(10); return ViewUtil.buildStandardJsonViewByObj(test); } @RequestMapping(value = "/test1") public ModelAndView myTest1() { String yanyi = testService.test1("yanyi"); return ViewUtil.buildStandardJsonViewByObj(yanyi); } }

TestService.java

public interface TestYanyiService {
    int test(int i); String test1(String i1); }

TestServiceImpl.java

import org.springframework.stereotype.Service;

@Service
public class TestYanyiServiceImpl implements TestYanyiService { @Override @CacheRedis(key = "test",expireTime = 10) public int test(int i) { return 0; } @Override @CacheRedis(key = "test1") public String test1(String i1) { return i1; } }

コードの完了後、あなたはPOMで依存ファイルをインポートする必要があります。

            <dependency>
                <groupId>aopalliance</groupId> <artifactId>aopalliance</artifactId> <version>1.0</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjrt</artifactId> <version>1.8.13</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>

この1に注意を払う必要があります:バージョンaspectjweaverパッケージおよびJDKのバージョンが関連しています。JDK 1.7以上のユーザーは、バージョンがaspectjweaver必要な場合はパッケージが低すぎる( - aspectJ1.7.3 + JDK1.7)をすることはできません。それ以外の場合はエラーになります::: 0時エラーエラーは、参照さ見つけることができないポイントカットを。

次に、Spring構成ファイルに次の

<!-- 启动对@AspectJ注解的支持 -->  
<aop:aspectj-autoproxy/> 

<!--通知spring使用cglib而不是jdk的来生成代理方法 AOP可以拦截到Controller->  
<aop:aspectj-autoproxy proxy-target-class="true" />  

OK!完了すると、テストコールインタフェースは、あなたがコントロールウィンドウの関連セクションログの印刷クラスのフロントとリアを見ることができます。この時点で、我々は少し内側にその機能を実現することができるようになります。(私はここでRedisのキャッシュ機能を実装する準備ができています。)

おすすめ

転載: www.cnblogs.com/exmyth/p/11495006.html