【春】AOPベース

AOPの概要

  AOPAspect Oriented Programing)、アスペクト指向プログラミング、伝統的な縦連続反復符号化システム(パフォーマンス監視、トランザクション管理、セキュリティチェック、キャッシュ)置換AOP取ら横抽出機構
  スプリングAOP純粋なJava実装、特別なタイプのコンパイルプロセスとをでローダランタイムプロキシ方法を介して標的クラスを強化するためにコードに織り込ま
  AspecJは、 JavaベースのAOPフレームワークであり、アスペクトの導入のために、スプリングAOPサポートを開始Spring2.0、AspectJのは、Java言語を拡張する特別を提供しますコンパイラは、コンパイル時にコードに横織物を提供します

AOPの用語:

  • 接続点(ジョインポイント):いわゆる接続点は、それらの点が傍受されています。Springあるため、これらの点は、方法を指すSpringのみサポートメソッド型接続ポイント。
  • エントリポイント(ポイントカット):いわゆるエントリーポイントは、私たちがしたいことを指しJoinpoint傍受を定義します。
  • 通知/強化(助言):いわゆる通知傍受することを意味しJoinpoint実行する事が知らせることです後。
    • (アドバイスの前に)事前通知:ターゲット・メソッドを呼び出す前に、呼び出し通知方法を
    • (最終的にアドバイス/後)アドバイスを帰国後:ターゲットメソッドを完了した後に呼び出し通知方法、方法が出力され、この時点では何も気にしません
    • (アドバイスを戻した後)戻り通知:ターゲット・メソッドが正常に実行された後着信通知
    • (アドバイスを投げた後に)例外通知:ターゲット・メソッド例外投げた後に着信通知を
    • (アドバイスアラウンド)アドバイス周り:通知方法を通知する方法では、通知に包まれている呼び出し前呼び出し後にカスタム動作を実行します
  • 導入/導入(導入):前提クラスコードを変更することなく、特別な通知される導入、はじめにランタイム・クラスを動的にすることができる追加またはメソッドフィールド
  • 聴衆(ターゲット):プロキシターゲットオブジェクト
  • (ウィービング)を織り:それに適用される拡張を意味対象物体ために作成し、新しいプロキシオブジェクト。プロセスSpringに織り込ま動的プロキシ、及びAspectJコンパイル時の織り織りクラスの使用期間にロードされ
  • プロキシ(プロキシ):クラスがあるAOP編まれた強化は、プロキシクラスの結果を生成し、
  • :セクション(アスペクト)結合およびエントリポイント通知(導入)の

    そして接続点複数のプログラムの実行に織り込ま部(通知)機能することができます
    そして接続点複数のプログラムの実行に織り込ま部(通知)機能することができます

用語AOP
用語AOP

AOP基本原理

SpringAOP実装メカニズムは、主に2つです:

  1. JDKダイナミックエージェント:インターフェース生成エージェントを実装するクラス
  2. CGLibプロキシのメカニズム:プロキシクラスを生成します

参照してください。プロキシモードを

春AOPで

アウトライン

分類

  1. エージェントベースの古典的な春AOP(伝統的なAOP)
  2. 純粋なPOJO部と、
  3. @AspectJアノテーション駆動部と
  4. (春バージョンの)注射AspectJのアスペクト。

伝統的な春AOP

  AOPは:組織の定義.AOP連合は春で定義されていません。

通知:(強化コードで春)

  1. インターフェイスの強化が達成されるように、ターゲットメソッドの実行前に実装:フロント予告org.springframework.aop.MethodBeforeAdvice
  2. ポストの通知:ターゲット・メソッドの後に行うの強化の実施形態では、インターフェースを達成することが、org.springframework.aop.AfterReturningAdvice
  3. アドバイス周り:行っ強化されたターゲット方法の実施形態の前と後に、インターフェースが達成すべき、org.aopalliance.intercept.MethodInterceptor
  4. 例外が通知をスローされます強化メソッドの実装は、例外をスローした後、インターフェイスを実装するために、org.springframework.aop.ThrowsAdvice
  5. 予告の紹介:インターフェイスを実装するために、ターゲットクラスにいくつかの新しいメソッドとプロパティを追加し、org.springframework.aop.IntroductionInterceptor

増強:(セクションカット点なしのすべての方法のために)

Mavenの座標の導入が必要です。

<!-- https://mvnrepository.com/artifact/org.springframework/spring-core -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>5.1.5.RELEASE</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-test -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>5.1.5.RELEASE</version>
            <!-- 这里要注释掉,因为设置了scope为test是,测试类只能卸载 Maven中的测试包下 -->
            <!-- <scope>test</scope> -->
        </dependency>

プロキシオブジェクトを書きます

インタフェース:

public interface ICustomerDao {
    public void add();
    public void update();
    public void delete();
    public void find();
}

クラスの実装:

public class CustomerDaoImpl implements ICustomerDao {
    @Override
    public void add() {
        System.out.println("添加客户");     
    }
    @Override
    public void update() {
        System.out.println("更新客户");
    }
    @Override
    public void delete() {
        System.out.println("删除客户");
    }
    @Override
    public void find() {
        System.out.println("查询客户");
    }
}

書かれた強化コード

フロントの強化:

import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        // TODO Auto-generated method stub
        System.out.println("前置增强。。。。。");
    }

}

:()XMLのプロキシ設定生成剤を生成します

<!-- 不带有切点的切面 -->
    <!-- 1.定义目标对象 -->
    <bean id="customerDao"
        class="com.hao.aop.tradition.demo1.CustomerDaoImpl"></bean>

    <!-- 2.定义增强 -->
    <bean id="beforeAdvice"
        class="com.hao.aop.tradition.demo1.MyBeforeAdvice"></bean>

    <!-- 3.Spring支持配置生成代理: -->
    <bean id="customerDaoProxy"
        class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 设置目标对象 -->
        <property name="target" ref="customerDao" />

        <!-- 设置代理要实现的接口 -->
        <property name="proxyInterfaces"
            value="com.hao.aop.tradition.demo1.ICustomerDao"></property>

        <!-- 设置需要织入目标的Advice -->
        <property name="interceptorNames" value="beforeAdvice" />
    </bean>

XMLでの設定手順:

  • 首先要将前面定义的目标对象增强 注册到Spring 容器中,
  • 然后是代理类的配置(主要是这里的配置):
    通过类 org.springframework.aop.framework.ProxyFactoryBean 来设置代理对象,对于这个类,以后有时间要看一下,下面先看一下它在XML中需要配置的属性:

    • target : 代理的目标对象
    • proxyInterfaces : 代理要实现的接口,如果多个接口可以使用以下格式赋值:

      <list>
          <value></value>
      ....
      </list>
    • proxyTargetClass:是否对类代理而不是接口,设置为true时,使用CGLib代理

    • interceptorNames : 需要织入目标的Advice

    • singleton : 返回代理是否为单实例,默认为单例

    • optimize : 当设置为true时,强制使用CGLib

测试

这里要注意的是,要注入代理对象!!!!

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AOPTest1 {

    @Qualifier("customerDaoProxy")
    @Autowired
    private ICustomerDao customerDao;
    
    @Test
    public void test() {
        customerDao.add();
        customerDao.find();
        customerDao.update();
        customerDao.delete();
    }
}

带有切点的切面:(针对目标对象的某些方法进行增强)

创建目标对象:

这里没有实现接口,这里试下用CGLIB代理的方式

public class OrderDao {
    public void add() {
        System.out.println("添加订单");
    }
    public void delete() {
        System.out.println("删除订单");
    }
    
    public void find() {
        System.out.println("查询订单");
    }
}

编写增强的类:

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyAroundAdvice implements MethodInterceptor{

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("执行方法之前增强.....");
        Object result = invocation.proceed();
        System.out.println("指向方法之后增强.....");
        return result;
    }

}

生成代理(配置生成代理):

<!-- 定义带有切点的切面 -->
    
    <!-- 定义目标对象 -->
    <bean id="orderDao" class="com.hao.aop.tradition.demo2.OrderDao"></bean>
    
    <!-- 定义增强 -->
    <bean id="aroundAdvice"
        class="com.hao.aop.tradition.demo2.MyAroundAdvice"></bean>
    
    <!-- 定义切面 -->
    <bean id="myPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <!-- 定义表达式,规定哪些方法执行拦截 -->
        <!-- . 任意字符  * 任意个 -->
        <property name="patterns" value=".*add.*,.*find.*"></property>
        
        <!-- 应用增强 -->
        <property name="advice" ref="aroundAdvice"/>
    </bean>
    
    <!-- 定义生成代理对象 -->
    <bean id="orderDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 配置目标 -->
        <property name="target" ref="orderDao"></property>
        <!-- 针对类的代理 -->
        <property name="proxyTargetClass" value="true"></property>
        <!-- 在目标上应用增强 -->
        <property name="interceptorNames" value="myPointcutAdvisor"></property>
    </bean>

测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class AOPTest2 {

    @Qualifier("orderDaoProxy") //此处注入的是代理对象
    @Autowired
    private OrderDao orderDao;
    
    @Test
    public void test() {
        orderDao.add();
        orderDao.delete();
        orderDao.find();
    }
}

自动代理

  前面的案例中,每个代理都是通过ProxyFactoryBean织入切面代理,在实际开发中,非常多的Bean每个都配置ProxyFactoryBean开发维护量巨大

  自动创建代理(基于后处理Bean,在Bean创建的过程中完成的增强,生成Bean就是代理。前面利用ProxyFactoryBean代理的方式需要先生成代理对象才可以实现代理功能,而这种方式在Bean的创建过程中就可以完成代码的增强)
  

  • BeanNameAutoProxyCreator:根据Bean名称创建代理
  • DefaultAdvisorAutoProxyCreator:根据Advisor本身包含信息创建代理
  • AnnotationAwareAspectJAutoProxyCreator:基于Bean中的AspectJ 注解进行自动代理

BeanNameAutoProxyCreator

  目标对象和增强,应用前面中的例子,配置示例:
  

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <!-- 定义目标对象 -->
    <bean id="customerDao" class="cn.itcast.spring3.demo3.CustomerDaoImpl"></bean>
    <bean id="orderDao" class="cn.itcast.spring3.demo4.OrderDao"></bean>

    <!-- 定义增强 -->
    <bean id="beforeAdvice" class="cn.itcast.spring3.demo3.MyBeforeAdvice"></bean>
    <bean id="aroundAdvice" class="cn.itcast.spring3.demo4.MyAroundAdvice"></bean>

    <!-- 自动代理:按名称的代理 基于后处理Bean,后处理Bean不需要配置ID-->
    <bean class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <property name="beanNames" value="*Dao"/>
        <property name="interceptorNames" value="aroundAdvice"/>
    </bean>
    
</beans>

测试代码:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.hao.aop.tradition.demo1.ICustomerDao;
import com.hao.aop.tradition.demo2.OrderDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext2.xml")
public class AOPTest3 {
    
    @Qualifier("customerDao")
    @Autowired
    private ICustomerDao customerDao;
    
    @Qualifier("orderDao")
    @Autowired
    private OrderDao orderDao;

    @Test
    public void test() {
        orderDao.add();
        orderDao.find();
        customerDao.add();
        customerDao.delete();
    }
}

DefaultAdvisorAutoProxyCreator

根据切面本身包含信息创建代理
配置示例:

<!-- 目标对象 -->
    <bean id="customerDao" class="com.hao.aop.tradition.demo1.CustomerDaoImpl"></bean>
    <bean id="orderDao" class="com.hao.aop.tradition.demo2.OrderDao"></bean>
    
    <!-- 定义增强-->
    <bean id="beforeAdvice" class="com.hao.aop.tradition.demo1.MyBeforeAdvice"></bean>
    <bean id="aroundAdvice" class="com.hao.aop.tradition.demo2.MyAroundAdvice"></bean>

    <!-- 定义一个带有切点的切面 -->
    <bean id="myPointcutAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <property name="pattern" value=".*add.*"/>
        <property name="advice" ref="aroundAdvice"/>
    </bean>
    
    <!-- 自动生成代理 -->
    <bean class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator"></bean>

测试代码:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.hao.aop.tradition.demo1.ICustomerDao;
import com.hao.aop.tradition.demo2.OrderDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext3.xml")
public class AOPTest4 {

    @Autowired
    @Qualifier("customerDao")
    private ICustomerDao customerDao;
    
    @Autowired
    @Qualifier("orderDao")
    private OrderDao orderDao;
    
    @Test
    public void test() {
        customerDao.add();
        customerDao.update();
        
        orderDao.add();
        orderDao.delete();
    }
}

区别:基于ProxyFattoryBean的代理与自动代理

  • ProxyFactoryBean:先有被代理对象,将被代理对象传入到代理类中生成代理.
  • 自动代理基于后处理Bean.在Bean的生成过程中,就产生了代理对象,把代理对象返回.生成Bean已经是代理对象.

AspectJ

概述

AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
AspectJ是一个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP

AspectJ表达式

  春AOPでは、カットオフポイントを定義するためにAspectJのポイントカット表現言語を使用します。春AOP AspectJのカットオフポイントについて、最も重要な点は、春(AspectJのが唯一のポイント・インジケーターをカットサポートしていることであるpointcut designator)サブセットです。スプリングは、エージェント・ベースであり、いくつかのカット点の発現は、プロキシベースのAOPとは無関係です。次のように春AOPはAspectJの接線ポイントインジケータをサポート:

あなたは春に他の指標にAspectJを使用しようとすると、IllegalArgument-例外例外がスローされます。インジケータに示すように、我々は、これらばね支持を見ると、他の指標が一致を制限するために使用されている間のみ実行インジケータは、マッチングの実用的な実装であることに注意。これは、実行が定義されているカットポイントの製造に使用される私たちの最も重要な指標の指標であることを示しています。これに基づいて、我々は、一致するカットオフポイントを制限するために他の指標を使用します。

実行式の構文:

実行(<アクセス修飾子> <?戻り値の型> <メソッド名>(<パラメータ>)<例外>)


  我々は使用 execution() を選択し、ポインタを する方法を。表現の方法は、することが 、我々はこの方法は、値の型を返す気にしないことを示す、番号を開始します。その後、私たちは、クラス名とメソッド名の完全修飾名を指定します。メソッドのパラメータリストについては、我々は2つのドットの使用 任意の選択したテーブルMingqieポイントを 関係なく、上院Yesにする方法の、方法を。 Performance perform() “*” (..) perform()

  请注意我们使用了“&&”操作符把execution()within()指示器连接在一起形成与(and)关系(切点必须匹配所有的指示器)。类似地,我们可以使用“||”操作符来标识或(or)关系,而使用“!”操作符来标识非(not)操作。
  因为“&”在XML中有特殊含义,所以在Spring的XML配置里面描述切点时,我们可以使用and 来代替“&&”。同样,ornot可以分别用来代替“||”“!”

AspectJ增强:

  • @Before 前置通知,相当于BeforeAdvice
  • @AfterReturning 后置通知,相当于AfterReturningAdvice
  • @Around 环绕通知,相当于MethodInterceptor
  • @AfterThrowing抛出通知,相当于ThrowAdvice
  • @After 最终final通知,不管是否异常,该通知都会执行
  • @DeclareParents 引介通知,相当于IntroductionInterceptor (了解)

开发步骤

开发之前需要引入依赖

<!-- https://mvnrepository.com/artifact/org.springframework/spring-aspects -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.1.5.RELEASE</version>
</dependency>

基于XML

第一步:编写被增强的类:

 public class ProductDao {
    public int add(){
        System.out.println("添加商品...");
        int d = 10/0;
        return 100;
    }
    public void update(){
        System.out.println("修改商品...");
    }
    public void delete(){
        System.out.println("删除商品...");
    }
    public void find(){
        System.out.println("查询商品...");
    }
}   

第二步:定义切面

import org.aspectj.lang.ProceedingJoinPoint;
/**
 * 切面类
 * @author hao
 *
 */
public class MyAspectXML {
    
    public void before(){
        System.out.println("前置通知...");
    }
    
    public void afterReturing(Object returnVal){
        System.out.println("后置通知...返回值:"+returnVal);
    }
    
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
        System.out.println("环绕前增强....");
        Object result = proceedingJoinPoint.proceed();
        System.out.println("环绕后增强....");
        return result;
    }
    
    public void afterThrowing(Throwable e){
        System.out.println("异常通知..."+e.getMessage());
    }
    public void after(){
        System.out.println("最终通知....");
    }
}

第三步:配置applicationContext.xml

<!-- 定义目标对象 -->
    <bean id="productDao" class="com.hao.aop.aspectj.xml.ProductDao"></bean>
    
    <!-- 定义增强 -->
    <bean id="myAspectXML" class="com.hao.aop.aspectj.xml.MyAspectXML"></bean>
    
    <aop:config>
        <!-- 定义切点: -->
        <aop:pointcut id="mypointcut" expression="execution(* com.hao.aop.aspectj.xml.ProductDao.add(..))" />
        <aop:aspect ref="myAspectXML">
            <!-- 前置通知 -->
            <aop:before method="before" pointcut-ref="mypointcut"/>
            <!-- 后置通知 -->
            <aop:after-returning method="afterReturing" pointcut-ref="mypointcut" returning="returnVal"/>
            
            <!-- 环绕通知 -->
            <aop:around method="around" pointcut-ref="mypointcut"/>
             
            <!-- 异常通知 -->
            <aop:after-throwing method="afterThrowing" pointcut-ref="mypointcut" throwing="e"/>
            <!-- 最终通知 -->
            <aop:after method="after" pointcut-ref="mypointcut"/>
        </aop:aspect>
    </aop:config>
基于注解

第一步:导入aop模块;Spring AOP:(spring-aspects)
第二部:定义一个业务逻辑类:在业务逻辑运行的时候将日志进行打印(方法之前、方法运行结束、方法出现异常,xxx)

public class UserDao {
    public void add(){
        System.out.println("添加用户");
    }
    public int update(){
        System.out.println("修改用户");
        return 1;
    }
    public void delete(){
        System.out.println("删除用户");
    }
    public void find(){
        System.out.println("查询用户");
        //int d = 1/ 0;
    }
}

第三步:定义一个切面类:切面类里面的方法需要动态感知业务类的方法运行到哪里然后执行;

  1. 给切面类的目标方法标注何时何地运行(通知注解);
  2. 必须告诉Spring哪个类是切面类(给切面类上加一个注解:@Aspect)
/**
 * 切面类:就是切点与增强结合
 * 
 * @author hao
 *
 */
@Aspect
public class MyAspect {

    // 定义一个切点
    @Pointcut("execution(* com.hao.aop.aspectj.anno.UserDao.find(..))")
    private void myPointcut() {} // 此方法没有实际的意义,就是为了提供给注解一个修饰的地方

    @Before("execution(* com.hao.aop.aspectj.anno.UserDao.add(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("前置增强...." + joinPoint);
    }

    @AfterReturning(value = "execution(* com.hao.aop.aspectj.anno.UserDao.update(..))", returning = "returnVal")
    public void afterReturin(Object returnVal) {
        System.out.println("返回增强....方法的返回值:" + returnVal);

    }

    @Around(value = "MyAspect.myPointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前增强....");
        Object obj = proceedingJoinPoint.proceed();
        System.out.println("环绕后增强....");
        return obj;
    }
    @AfterThrowing(value = "MyAspect.myPointcut()", throwing = "e")
    public void afterThrowing(Throwable e) {
        System.out.println("不好了 出异常了!!!" + e.getMessage());
    }

    @After("MyAspect.myPointcut()")
    public void after() {
        System.out.println("最终/后置通知...");
    }

}

通知のAspectJのタイプ:

  • 事前通知(@Before):logStart:ターゲット・メソッドの前に実行されている(DIV)の実行
  • ターゲットメソッド(DIV)の実行が終了した後(関わらず、正常または異常終了の方法の)実行:logEnd:アドバイス(@After)を帰国後
  • リターン通知(@AfterReturning):logReturnは:(DIV)通常の状態に戻るには、ターゲットメソッドの後に実行します
  • 例外通知(@AfterThrowing):たlogException:ターゲット・メソッドの後に実行します(DIV)異常
  • アドバイス(@Around)周り:動的プロキシ、手動メソッドの実行の目標を進める(joinPoint.procced())
  • IntroductionInterceptorに相当する通知(@DeclareParents)、(マスターに必須ではない)を導入

カットオフポイントの定義:

// 定义一个切点
@Pointcut("execution(* com.hao.aop.aspectj.anno.UserDao.find(..))")
private void myPointcut() {} // 此方法没有实际的意义,就是为了提供给注解一个修饰的地方

顧問とアスペクトの違いは?

  • 顧問:支持点のカットや通知の組み合わせ:伝統的な意味で切断春。
  • アスペクト:複数のカットポイントと複数の通知の組み合わせをサポートすることができます。

ステップ4:注釈を有効にし、クラスおよびビジネス・ロジック・クラス(クラスターゲットメソッド)をカットが容器に添加されています

XMLの通り:

<!-- 自动生成代理  底层就是AnnotationAwareAspectJAutoProxyCreator -->
    <aop:aspectj-autoproxy />

    <bean id="userDao" class="com.hao.aop.aspectj.anno.UserDao"></bean>
    <bean id="myAspect" class="com.hao.aop.aspectj.anno.MyAspect"></bean>

注釈の道

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@EnableAspectJAutoProxy
@Configuration
public class MainConfigOfAOP {
    //业务逻辑类加入容器中
    @Bean 
    public UserDao userDao(){
        return new UserDao();
    }
    //切面类加入到容器中
    @Bean
    public MyAspect myAspect(){
        return new MyAspect();
    }
}

  コンフィギュレーション・クラスに加えて@EnableAspectJAutoProxyスプリング多く@EnableXXX(その原理を整理するのに時間がかかる)において、アノテーションベースのAOPモードを[開きます]。

概要
  1. ビジネス・ロジック・コンポーネントとカットクラスは容器に添加され、クラス(@Aspect)切断されたスプリングを伝えます
  2. いつ、どこで実行するように通知部注釈にマーククラスの各通知方法は、春には(ポイントカット式)を語りました
  3. AOPオープン注釈ベースのモデル; @EnableAspectJAutoProxy

原則の実現のためのAOPメカニズム(AnnotationAwareAspectJAutoProxyCreator)

基本原理AnnotationAwareAspectJAutoProxyCreator

「保留中仕上げ」...

おすすめ

転載: www.cnblogs.com/haoworld/p/spring-aop-base.html