在其他项目中用作编译jar时,Spring AOP无法正常工作

时间:2018-09-12 16:05:10

标签: java spring java-8 aspectj spring-aop

我有一个有效的AOP(在项目内部使用时被写入),但是当我构建该项目(maven安装),并在另一个项目中使用该JAR,并尝试使用@TimedLog批注时,什么都没发生。我试图在其中断点,但是它没有到​​达那里。

它看起来像这样:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface TimedLog {
    boolean shouldAttachMethodArgs() default false;
    boolean shouldAttachReturnValue() default false;
    String message() default "";
}

这是实际的方面:

@Aspect
@Configuration
@Slf4j
public class MethodExecutionAspect {

    @Pointcut("@annotation(timedLogVar)")
    public void annotationPointCutDefinition(TimedLog timedLogVar) {}

    @Pointcut("execution(* *(..))")
    public void atExecution() {}

    @Around(value = "annotationPointCutDefinition(timedLogVar) && atExecution()", argNames = "joinPoint,timedLogVar")
    public Object around(ProceedingJoinPoint joinPoint, TimedLog timedLogVar) throws Throwable {
        Stopwatch stopwatch = Stopwatch.createStarted();
        Object returnValue = joinPoint.proceed();
        stopwatch.stop();

        log.info(String.format("test message %s", stopwatch.elapsed(TimeUnit.MILLISECONDS)));

        return returnValue;
    }
}

它的实现是:

@TimedLog
void testDefaultValues() throws InterruptedException {
    int sleepTimeInMillis = 200;
    log.info("Resting for {} millis", value("sleepTimeInMillis", sleepTimeInMillis));
    Thread.sleep(sleepTimeInMillis);
}

pom.xml

<!-- AOP -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aop</artifactId>
    <version>5.0.2.RELEASE</version>
    <scope>compile</scope>
</dependency>
<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.8.13</version>
    <scope>compile</scope>
</dependency>

从这里您可以看到,这是一个装饰方法并记录其运行时的AOP。

我已经为此苦苦挣扎了一段时间,非常感谢您的帮助。

谢谢

编辑: 根据要求,使用该AOP的项目的完整pom.xml(位于foo.bar.utilsutils-common

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>backend</artifactId>
        <groupId>foo.bar.backend</groupId>
        <version>2.0.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>backend-logic</artifactId>
    <repositories>
        <repository>
            <id>maven-s3-release-repo</id>
            <name>S3 Release Repository</name>
            <url>s3://repository.foobar.com/releases</url>
        </repository>
        <repository>
            <id>maven-s3-snapshot-repo</id>
            <name>S3 Snapshot Repository</name>
            <url>s3://repository.foobar.com/snapshots</url>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>foo.bar.backend</groupId>
            <artifactId>backend-contract</artifactId>
            <version>2.0.0-SNAPSHOT</version>
        </dependency>

        <!-- Spring boot actuator to expose metrics endpoint -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- Micormeter core dependecy  -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-core</artifactId>
        </dependency>
        <!-- Micrometer Prometheus registry  -->
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
        </dependency>

        <!-- Common -->
        <dependency>
            <groupId>foo.bar.utils</groupId>
            <artifactId>utils-common</artifactId>
            <version>1.0.0-SNAPSHOT</version>
        </dependency>

        <!-- Auth -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-security</artifactId>
            <version>2.0.0.M1</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- Utils -->
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>18.0</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.4</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-joda</artifactId>
        </dependency>
        <dependency>
            <groupId>joda-time</groupId>
            <artifactId>joda-time</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.16.4</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>4.5.1</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>

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

    </dependencies>
    <build>
        <extensions>
            <extension>
                <groupId>org.springframework.build</groupId>
                <artifactId>aws-maven</artifactId>
                <version>5.0.0.RELEASE</version>
            </extension>
        </extensions>
    </build>

</project>

EDIT2: 无效的实现(在应该使用AOP的其他项目中)

@Slf4j
@Configuration
@EnableAspectJAutoProxy
public class TestingSomething {

    @TimedLog(message = "test something")
    public void testingSomething() {
        log.info("ololol");
    }

}

然后是测试,对其进行测试:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SomeSpringConfiguration.class,
        properties = {"server.port=0", "enable.security=true"})
@WebAppConfiguration
public class testingSomethingTest {
    @Autowired
    TestingSomething testingSomething;

    @Test
    public void testingLol() {
        testingSomething.testingSomething();
    }
}

1 个答案:

答案 0 :(得分:3)

要使各方面正常工作,您需要启用它们。要启用它,您需要通过xml或通过注释配置它们:

@Configuration
@EnableAspectJAutoProxy

通过xml:

<beans …>
      <!– Enable AspectJ auto-wiring –>
      <aop:aspectj-autoproxy />
</beans>

将jar包含在另一个应用程序中时,该另一个应用程序具有自己的配置和上下文。即使您为原始上下文启用了方面自动装配,您仍然需要通过上述两种方式之一对新应用程序执行相同的操作。

如果您使用注释,请确保它在组件扫描范围之内并且确实包含在您的上下文中。

更新: 对您的testingSomethingTest做@Import (MethodExecutionAspect.class),以确保对其进行了组件扫描。