切断面とユーザー定義の注釈の配合使用


一.概要
       カットに基づいたプログラミング(AOP)はよく知られていないかもしれません.しかし、切面にも欠点があります.筆者の経験から見れば、切面の不便さは切面の精度の問題にあります.大量の指定種類の指定方法に事務を加えるのは難しいです.ここではSpring AOPとカスタム注釈の協力によってこの問題を解決します.
二.Spring AOPカットの使用と問題
使用:       事務を例にとって、私達はJ 2 EEプロジェクトの枠組みを作る時、必ず事務を処理します.通常私達のやり方はサービス層のDLL操作方法に事務を追加します.具体的なコードは以下の通りです.
//         
<tx:advice id="txAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="add*"     propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="save*"    propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="insert*"  propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="update*"  propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="modify*"  propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="delete*"  propagation="REQUIRED"  rollback-for="Exception" />
        <tx:method name="remove*"  propagation="REQUIRED"  rollback-for="Exception" />
    tx:attributes>
tx:advice>

    <aop:config proxy-target-class="true">
        <aop:advisor pointcut="execution(* com.etc..service.impl.*ServiceImpl.*(..))" advice-ref="txAdvice" />
    aop:config>
       上の配置によって、事務の処理が実現できますが、この配置は非常に柔軟ではなく、彼はクラスを制限しました.次に、方法名はadd、save、insertなどで始めなければなりません.新しい需要:
       以前の開発では、システムの一部の業務方法が呼び出された時に、ログにログを挿入する必要があります.業務方法名が規則的ではないので、すべての業務方法名を上に配置することはできません.問題は来ました.ログを記録する方法ごとに、Spring AOPを感知する文法がありますか?これは以下の説明です.カスタムコメントです.
三.カスタムコメント
       Annotation(注)はJDK 1.5以降に導入される新しい特性です.「@注名」という形でコードに存在します.クラス、方法、属性の上に表示されます.注釈が付けられたら、コンパイル期間または実行期間にどのような種類、どのような方法、または属性が注釈されているかを動的に取得できます.属性と方法は対応する処理を行って、正式にこの特性のため、やっと私達の上述の問題を解決することができます.どのようにコメントをカスタマイズしますか?
       ユーザー定義の注釈を理解するには、元の注釈が必要です.元の注釈の役割は他の注釈を注釈することです.Java 5.0は、他のannotationタイプについて説明するために使用される4つの標準的なmeta-annotationタイプを定義している.Java 5.0定義のメタ注釈:
@Target       @TargetはAnnotationで修飾されたオブジェクト範囲を説明しています.Annotationは、packages、types(クラス、インターフェース、列挙、Annotationタイプ)、タイプメンバー(方法、構造方法、メンバー変数、列挙値)、方法パラメータおよびローカル変数(例えば、循環変数、catchパラメータ)に使用できます.Annotationタイプの声明では、targetを使用して、その修飾の目標をより明確にすることができる.
@レジェンド       @Retensionは、Annotationが保持されている時間の長さを定義しています.いくつかのAnnotationはソースコードにのみ表示され、コンパイラによって破棄されます.他のいくつかはクラスファイルにコンパイルされています.classファイルにコンパイルされたAnnotationは仮想マシンに無視されるかもしれませんが、他のいくつかはクラスにロードされた時に読み取られます.このmeta-Annotationを使うとAnnotationの「ライフサイクル」が制限されます.例えば私たちがよく見ている@Overrideの注釈は彼の@Retensionはsourceの段階にあります.彼は方法のカバーに対して文法検査をするだけです.ルールさえ合えばいいです.運行段階では必要ないです.
@Dcumented       @Dcumentedは、他のタイプのannotationが表示されるプログラムメンバーの共通APIとして機能するべきであることを記述するために使用されるので、例えばjavadocのようなツールドキュメント化が可能である.Dcumentedは、メンバーがいません.
@Inheited       @Inherited元の注釈は表記の解釈であり、@Inheritedはある種類の表記が継承されていると述べています.@Inherited修飾を使用したannotationタイプが一つのクラスに使用されると、このannotationはそのクラスのサブクラスに使用されます.
四.具体的な実現
コメントコード:
@Target({ElementType.PARAMETER, ElementType.METHOD})    
@Retention(RetentionPolicy.RUNTIME)    
@Documented   
public @interface LogOperation {

}
       ,     ,        ,           。
面コード:
@Aspect
@Component
public class LogOperationAspect {

    Logger log = LoggerFactory.getLogger(LogOperationAspect.class);

    @Autowired
    ILogOperationService logOperationService;


    //       ,                
    @Pointcut("@annotation(com.etc.annotation.LogOperation)")
    public void controllerAspect() {
    }

    //          
    @Before("controllerAspect()")
    public void beforeMethod(JoinPoint joinPoint) {
        //            
        this.saveLogOperation(joinPoint, StatusEnum.SUCCESS);
    }
}
面のコードを使う:
//            ,        
@LogOperation
@ResponseBody
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
public Map getDemo(@PathVariable Integer id, HttpServletRequest request,
        HttpServletResponse response) {
    DemoVO vo = this.demoService.selectById(id);
    return ResultMapper.convertSuccess(vo);
}
五.まとめ
       上記のコードを通じて、私達は日記を記録することを望む方法に@LogOperation注釈を追加すれば、この方法の動作はログに記録されます.方法の名前は何ですか?種類はどこにありますか?