第 28 章 実践事例: アスペクト指向プログラミングのための Spring アノテーションに基づく AOP の構成

エピソード1 Spring AOPアノテーションの基本的な準備

はじめに: Spring AOPアノテーションの基本的な準備について説明します 

  • アスペクトクラス@Aspect ( aspect ) を宣言します。通常は、ポイントカットと通知を定義できるクラスです。 
  • エントリポイントと通知の構成 (第 2 章 LogAdvice クラス)

 エピソード2では、 Spring AOPアノテーションの構成とスキャンを開始します

はじめに: Open Spring AOPアノテーションとスキャン 

  • Spring AOPアノテーション構成を有効にする 

@Configuration //需要得到一个注解配置类
@ComponentScan("xj.com")  //扫com以下的包 相当于 context.scan("xj.com") 操作
//开启spring对aspect支持
@EnableAspectJAutoProxy
public class AnnotationAopConfiguration {
        //这是一个AOP的配置类
}

セクション クラス: コンポーネントを追加する必要があります。追加しない場合、このファイルはスキャンできません

@Component //注册bean
@Aspect //告诉Spring这是一个切面类,里面可以定义切入点和通知方法
public class LogAdvice { //注解完成切面功能
    //定义一个切入点
    @Pointcut(value = "execution(* xj.com.springDemo.service.impl.VideoServiceImpl.*(..))")
    public void PointCut(){ }

    //定义一个前置通知
    @Before("PointCut()")
    public void befor(){
        System.out.println("前置增强处理");
    }
}

VideoService 実装クラス: サービス アノテーションも追加する必要があります。追加しないと Bean をスキャンできません

@Service("videoService")
public class VideoServiceImpl implements VideoService {

    public int addOrder(VideoOrder videoOrder) {
        System.out.println("使用addOrder方法");
        return 0;
    }

    public Long delOrder(VideoOrder videoOrder) {
        System.out.println("使用delOrder方法");

        return null;
    }

    public List<VideoOrder> findOrderById() {
        System.out.println("使用findOrderById方法");
        return null;
    }

    public int updateOrder(VideoOrder videoOrder) {
        System.out.println("使用updateOrder方法");
        return 0;
    }

    public int save(Video video) {
        System.out.println("存一条视频");
        return 0;
    }
}

テスト クラス; getBean はもはやインターフェースではなく、AOP 構成クラスであることに注意してください。これを使用すると、すべての構成クラスがアノテーションを使用して構成されているため、リフレッシュ操作とスキャン操作を記述する必要がありません。

  /**
     * 使用注解打印日志处理
     */
    @Test
    public void Test3(){
        //1.需要配置AOP配置类
        //2.使用注解方式创建context
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAopConfiguration.class);
        //3.获得一个配置类中的bean
        VideoService videoService =(VideoService) context.getBean("videoService");

        //4.执行方法 同时会被通知切入进去
        videoService.addOrder(new VideoOrder());

    }

操作結果: 

エピソード3 AOP事件 周囲の実際の戦闘 通知統計インターフェース 時間がかかる 

はじめに: AOPサラウンド通知統計手法による通話に時間がかかる 

  • ラップアラウンド通知の構成: メソッド要求の経過時間を印刷する 
  • 通知周りのターゲットメソッドとパラメータを取得します。
周囲のコード: コア コード ( ターゲット クラスがどのような型を返すか、どのような型を返す必要があるかに注意してください )
  //使用环绕通知
    @Around(value = "execution(* xj.com.springDemo.service.impl.VideoServiceImpl.*(..))")
    public int around(JoinPoint joinPoint){ //joinPoint可以查看调用的方法,以及调用者
        //查看调用者
        Object target = joinPoint.getTarget().getClass().getName();
        //xj.com.springDemo.service.impl.VideoServiceImpl
        System.out.println("调用者="+target);

        //目标方法签名--也就是调用的方法名字
        System.out.println("调用方法="+joinPoint.getSignature());

        //获取方法参数
        Object[] args = joinPoint.getArgs();

        long start = System.currentTimeMillis();
        System.out.println("环绕通知 环绕前=========");
        //执⾏连接点的⽅法
        try {
            ((ProceedingJoinPoint) joinPoint).proceed(); //执行实现类的方法
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("环绕通知 环绕后=========");

        System.out.println("时间消耗"+(end-start));

        return 1;
    }

実装クラス:

public class VideoServiceImpl implements VideoService {

    public int addOrder(VideoOrder videoOrder) {
        System.out.println("使用addOrder方法");

        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        return 0;
    }
}

テストクラス:

@Test
    public void Test3(){
        //1.需要配置AOP配置类
        //2.使用注解方式创建context
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnnotationAopConfiguration.class);
        //3.获得一个配置类中的bean
        VideoService videoService =(VideoService) context.getBean("videoService");

        //4.执行方法 同时会被通知切入进去
        int i = videoService.addOrder(new VideoOrder());
        System.out.println("返回值"+i);

    }

実行結果:aroundクラスの戻り値が返され、aroundが実装クラスの戻り値をオーバーライドすることがわかります。

 

おすすめ

転載: blog.csdn.net/LiuJia20010827/article/details/126198795