2017-10-12 15 views
2

私はspring aopをSpringブートプロジェクトで使用しようとしています。メインクラスのジョイントポイントで私が練習したアドバイスを得られない理由はわかりません。 AOPはサービスクラスでうまく機能しています。コードは以下の通りです。Spring AOPはSpringブートプロジェクトでメインクラスで動作していませんか?

SpringBootWithAOP.java

package com.example.demo; 
import javax.annotation.PostConstruct; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 
import com.example.demo.services.SayHelloService; 

@SpringBootApplication 
public class SpringBootWithAOP { 

    @Autowired 
    SayHelloService service; 

    String message; 
    static String name; 

    public static void main(String[] args) { 
     name="George"; 
     SpringApplication.run(SpringBootWithAOP.class, args); 
    } 

    @PostConstruct 
    public void init() { 
     service.message(name); 
    } 
} 

SayHelloService.java

package com.example.demo.services; 
import org.springframework.stereotype.Service; 

@Service 
public class SayHelloService { 
    public String message(String name) { 
     System.out.println("Hello Dear User - " + name); 
     return "Hello Dear User - " + name ; 
    } 
} 

MasterLoggerAspect.java

package com.example.demo.aop; 
import org.aspectj.lang.JoinPoint; 
import org.aspectj.lang.annotation.Aspect; 
import org.aspectj.lang.annotation.Before; 
import org.aspectj.lang.annotation.Pointcut; 
import org.springframework.stereotype.Component; 

@Component 
@Aspect 
public class MasterLoggerAspect { 
    @Before("execution(* com.example.demo.services.*.*(..))") 
    public void doForEveryServicesMethod(JoinPoint jp){ 
     System.out.println("hurray! In class: " + jp.getSignature().getDeclaringTypeName() + " - before method: " + jp.getSignature().getName()); 
    } 
    //this advice is not getting weaved 
    @Before("execution(* com.example.demo.*.*(..)) ") 
    public void doForEveryMainClassMethod(JoinPoint jp){ 
     System.out.println("hurray! In class: " + jp.getClass() + " - before method: " + jp.getSignature().getName()); 
    } 
} 

pom.xmlにはspring-boot-starter-aopがあります。

問題のある箇所を示唆するものがあります。

出力 - ここで入手可能

hurray! In class: com.example.demo.services.SayHelloService - before method: message 
Hello Dear User - George 

コード:https://github.com/samshers/46692518/

答えて

0

"春AOPは、現在唯一の方法の実行は、(のSpring Beanにメソッドの実行を助言)ジョインポイントをサポートしています。"

私はアプリケーションEntrypointがBeanだとは思わない。

CommandLineRunnerインターフェイスを見て、実行をオーバーライドする独自のクラスを実装してください。コマンドラインランナーは、Beanが初期化されるとすぐに実行されます。

+0

GR8の答えがあります。私は '@ Component'アノテーションをメインクラスに追加しようとしました。それがうまくいくと思った。しかし、運がない。これは限界か、私は何かもっとやる必要があります。メインクラスにもAOPログを記録したい。 – samshers

+0

が回答を編集しました。上記のインターフェイスを実装する新しいクラスを作成し、テストが有効な場合はポイントカットを実行するようにしてください。 – LT56

+0

gr8。応答のためのthx。私はAOPを使って 'public static void main(String [] args){...}'をトレースすることにもっと悩まされています。これを達成するための何らかの方法がありますか? – samshers

4

サブパッケージを含めるには、サービスパッケージの後に2つのドット表記(..)を使用する必要があります。 * com.example.demo..*.*(..)の使用を開始すると、mainを除き、すべてのSpring管理Beanがログに記録され、メソッドには@PostConstructというタグが付けられます。 PostConstruct JavaDocによれば、このメソッドはクラスがサービスに入る前に呼び出さなければなりません。

@Component 
@Aspect 
public class MasterLoggerAspect { 

    @Pointcut("execution(* com.example.demo..*.*(..))") 
    public void logForAllMethods(){} 

    @Before("execution(* com.example.demo.services.*.*(..))") 
    public void doForEveryServicesMethod(JoinPoint jp){ 
     System.out.println("hurray! In class: " + jp.getSignature().getDeclaringTypeName() + " - before method: " + jp.getSignature().getName()); 
    } 

    @Before("execution(* com.example.demo..*.*(..))") 
    public void doForEveryMainClassMethod(JoinPoint jp){ 
     System.out.println("hurray! In class: " + jp.getClass() + " - before method: " + jp.getSignature().getName()); 
    } 
} 

あなたは春ブーツメインクラスに@Component注釈を追加し、別のクラスにそれをautowire場合、SpringBootWithAOPクラスで呼び出された任意の方法が記録されます。例えば、SayHelloServiceクラスへ

@SpringBootApplication 
@Component 
public class SpringBootWithAOP { 

    @Autowired 
    SayHelloService service; 

    String message; 
    static String name; 

    public static void main(String[] args) { 
     name="George"; 
     SpringApplication.run(SpringBootWithAOP.class, args); 
    } 

    public void sayHello() { 
     System.out.println("888888"); 
    } 

    @PostConstruct 
    public void init() { 
     service.message(name); 
    } 
} 

の変更、ここで

@Service 
public class SayHelloService { 

    @Autowired 
    SpringBootWithAOP aop; 

    public String message(String name) { 
     System.out.println("Hello Dear User - " + name); 
     aop.sayHello(); 
     return "Hello Dear User - " + name ; 
    } 
} 

が記録されたメッセージ、

hurray! In class: class org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint - before method: message 
hurray! In class: com.example.demo.services.SayHelloService - before method: message 
Hello Dear User - George 
hurray! In class: class org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint - before method: sayHello 
888888 
+1

素敵な回答インドラ –

+0

「とSpringBootWithAOPクラスで呼び出された任意の方法が記録されます、その後、別のクラスにそれをautowire」 - まあ、これが細かいですね。しかし、 'main'メソッドと' @ PostConstruct'メソッド( 'init')はまだjoinpointではありません。私はこれを達成する方法を知りたい。これらのメソッドが呼び出されたときにログに記録します。 – joveny

+0

あなたは絶対に正しいです!私はこれらの2つのメソッドがジョイントポイントではないという修飾子を使用していたはずです。あなたは[PostConstruct](https://docs.oracle.com/javase/7/docs/api/javax/annotation/PostConstruct.html)のJavaのドキュメントを見れば、あなたはクラスがサービスに入れていないことに気づくでしょうこのメソッドが呼び出されるまで –

関連する問題