スプリングAOP


1.概念紹介


計画(AOP)はOOPへの補完であり,ばらばらな計画をモジュール化できるプログラミング手法である.
分散した注目点

AOPを適用すると?

ex)トランザクション、レコード...

AOPキーコンセプト

  • 計画および目標
  • Advice
  • Join PointとPoint
  • Adviceはタスクを完了するために使用され、Pointcutはどこに適用すべきかを決定するために使用されます.
    ターゲットは上図でAクラス、Bクラス、Cクラスです.JoinPointは、関数呼び出しの前、メソッド呼び出しの前、フィールドアクセスの前など、挿入可能な任意のポイントです.
    https://velog.io/@jsj3282/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%82%BC%EA%B0%81%ED%98%95%EA%B3%BC-%EC%84%A4%EC%A0%95-%EC%A0%95%EB%B3%B42-AOP1

    AOPインプリメンテーション

  • https://en.wikipedia.org/wiki/Aspect-oriented_programming
  • Java
    - AspectJ
    -機能と接続点のみ(AssetJに対して)
  • AOPの適用方法

  • コンパイル
  • ロード時間
  • 運転時:スプリングに空を作成した時点が運転時です.したがって、Aクラスの空を作成すると、Aというタイプのエージェント空が作成され、エージェント空がAOPを実行してAが呼び出されます.
  • 2.エージェントベースAOP


    スプリングAOP特性

  • エージェントベースAOPインプリメンテーション
  • スプリングシートにのみ適用されます.
  • の目的は、すべてのAOP機能を提供することではなく、Spring IoCとともにエンタープライズアプリケーションで最も一般的な問題に解決策を提供することです.
  • プロキシモード


    https://velog.io/@jsj3282/%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%B4-%EC%82%AC%EB%9E%91%ED%95%9C-%EB%94%94%EC%9E%90%EC%9D%B8-%ED%8C%A8%ED%84%B41
  • どうしたの?(既存コードを変更する必要はない)アクセス制御または追加機能
  • を追加する.

    既存のコード
    public interface EventService {
    
        void createEvent();
        void publishEvent();
        void deleteEvent();
    
    }
    @Service
    public class SimpleEventService implements EventService{
    
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(2000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Published an event");
        }
        public void deleteEvent(){
            System.out.println("Delete an event");
        }
    }
    @Component
    public class AppRunner implements ApplicationRunner {
    
        @Autowired
        EventService eventService;
    
        @Override
        public void run(ApplicationArguments args) throws Exception {
            eventService.createEvent();
            eventService.publishEvent();
            eventService.deleteEvent();
        }
    }
  • の既存コードに触れずにパフォーマンスをテストします.(プロキシモード)
  • @Service
    public class SimpleEventService implements EventService{
        
        @Override
        public void createEvent() {
            long begin = System.currentTimeMillis();
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Created an event");
            System.out.println(System.currentTimeMillis() - begin);
        }
    
        @Override
        public void publishEvent() {
            long begin = System.currentTimeMillis();
            try {
                Thread.sleep(2000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Published an event");
            System.out.println(System.currentTimeMillis() - begin);
        }
        public void deleteEvent(){ // 이 메소드에서는 성능 측정 기능을 추가하고 싶지 않다.
            System.out.println("Delete an event");
        }
    }
    問題は、既存のコードに触れたくないことです.したがって、プロキシモードを使用します.
    @Primary
    @Service
    public class ProxySimpleEventService implements EventService{
    
        @Autowired
        EventService simpleEventService; // 빈의 이름에 기반해 SimpleEventService를 주입받는다.
    
        //@Autowired
        //SimpleEventService simpleEventService;
    
        @Override
        public void createEvent() {
            long begin = System.currentTimeMillis();
            simpleEventService.createEvent();
            System.out.println(System.currentTimeMillis() - begin);
        }
    
        @Override
        public void publishEvent() {
            long begin = System.currentTimeMillis();
            simpleEventService.publishEvent();
            System.out.println(System.currentTimeMillis() - begin);
        }
    
        @Override
        public void deleteEvent() {
            simpleEventService.deleteEvent();
        }
    }
    エージェントクラスが行った作業は、依存性を注入するSimpleEventServiceインスタンスに委任されていますが、パフォーマンスはエージェントクラスによって測定されます.
    注意:Webサーバモードで実行しない方法
    @SpringBootApplication
    public class Springtest11Application {
    
        public static void main(String[] args) {
            SpringApplication app = new SpringApplication(Springtest11Application.class);
            app.setWebApplicationType(WebApplicationType.NONE);
            app.run(args);
            //SpringApplication.run(Springtest11Application.class, args);
        }
    }

    に質問

  • エージェントクラスを作成するたびに必要ですか?
  • を複数のクラスの複数のメソッドに適用するには、次の手順に従います.
  • オブジェクト間の関係も複雑...
  • だから現れたのはスプリングAOPです。

  • スプリングIoCコンテナが提供するインフラストラクチャと動的エージェントを使用して、多くの複雑な問題を解決します.
  • 動的エージェント:エージェントオブジェクトを動的に作成する方法
    -Javaが提供する方法は、インタフェースベースのエージェントを作成することです.
    -CGlibはクラスベースのエージェントをサポートします.
  • スプリングIoC:既存のアイドルの代わりに動的エージェントを作成し、登録します.
    -クライアントコードは変更されません.
    - AbstractAutoProxyCreator implements BeanPostProcessor
  • 3. @AOP


    動画ベーススプリング@AOP

    依存項目の追加

    <dependency> 
    	<groupId>org.springframework.boot</groupId> 
    	<artifactId>spring-boot-starter-aop</artifactId> 
    </dependency>

    属性の定義

  • @Aspect
  • 空(コンポーネントスキャンを使用する場合)に登録する必要があるため、@コンポーネントも追加します.
  • ポイントカットの定義

  • @Pointcut(式)
  • 主な式
    - execution
    - @annotation
    - bean
  • 点カットセット
    - &&, ||, !
  • アドレスの定義

  • @Before
  • @AfterReturning
  • @AfterThrowing
  • @Around:メソッド呼び出し自体を囲み、メソッド呼び出しの前後でエラー処理を行うこともできます.
  • @Component
    @Aspect
    public class PerfAspect {
        //@Around("execution(* com.example..*.EventService.*(..))") 
        //com.example 패키지에 속한 EventService에 있는 모든 메서드에 적용한다.
        //@Around("@annotation(PerfLogging)")
        //PerfLogging 애노테이션이 달려있는 메소드에만 적용한다.
        @Around("bean(simpleEventService)")
        //빈의 모든 메서드에 적용된다.
        public Object logPerf(ProceedingJoinPoint pjp) throws Throwable{
            long begin = System.currentTimeMillis();
            Object retVal = pjp.proceed();
            System.out.println(System.currentTimeMillis() - begin);
            return retVal;
        }
    
        @Before("bean(simpleEventService)")
        public void hello(){
            System.out.println("Hello");
        }
    }
    /**
     * 이 애노테이션을 사용하면 성능을 로깅해 줍니다.
     */
    @Documented
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.CLASS)
    public @interface PerfLogging {
    }
    @Service
    public class SimpleEventService implements EventService{
        @PerfLogging
        @Override
        public void createEvent() {
            try {
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Created an event");
        }
    
        @PerfLogging
        @Override
        public void publishEvent() {
            try {
                Thread.sleep(2000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("Published an event");
        }
        public void deleteEvent(){
            System.out.println("Delete an event");
        }
    }
    宣言の作成時には、CLASS(default)以降に予約情報を提供する必要があります.SOURCEになるとコンパイル後のコメントは消えてしまいます.
    リファレンス
  • インフラストラクチャ:スプリングフレームキーテクノロジー(白旗線)
  • https://en.wikipedia.org/wiki/Aspect-oriented_programming
  • https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#aop pointcuts