Spring AOP没有在Spring Boot Project的主类中工作?

时间:2017-10-12 01:34:37

标签: spring spring-boot aop aspectj spring-aop

我试图在spring boot项目中使用spring aop。我不确定为什么我没有得到在主类的连接点编织的建议。 AOP在服务类中运行良好。代码如下。

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/

2 个答案:

答案 0 :(得分:3)

您需要在服务包之后使用两个点表示法(..)来包含子包。开始使用* com.example.demo..*.*(..)后,将记录除main之外的所有Spring托管bean以及标记为@PostConstruct的方法。根据{{​​3}},必须在类投入使用之前调用此方法。

@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注释添加到Spring Boot主类并将其自动装配到另一个类,则将记录在SpringBootWithAOP类中调用的任何方法。例如,

@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);
    }
}

SayHelloService类的更改,

@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)

“Spring AOP目前仅支持方法执行连接点(建议在 Spring beans 上执行方法)。”

我不相信应用程序Entrypoint是一个bean。

查看CommandLineRunner接口并实现自己的类覆盖run。命令行运行器将在bean初始化后立即运行。