【问题标题】:Spring AOP not working when using as a compiled jar in a different project在不同项目中用作已编译 jar 时,Spring AOP 不起作用
【发布时间】:2018-09-12 16:05:09
【问题描述】:

我有一个工作的 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.utils:utils-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>

编辑2: 不起作用的实现(在应该使用 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();
    }
}

【问题讨论】:

  • 你能把你项目的 pom 贴在你正在使用它的地方吗??
  • 使用您的 jar 的其他项目是否通过 @EnableAspectJAutoProxy 或通过 xml 配置启用了方面。你提到你正在使用你的 jar 作为库,我的假设是使用这个 jar 的项目也启用了方面?
  • @YatiSawhney 我使用编辑中的 jar 附加了项目的完整 pom.xml
  • 不要使用@Configuration 使用常规组件. The @EnableAspectJAutoProxy` 应该继续你的SomeSpringConfguration

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


【解决方案1】:

要使这些方面起作用,您需要启用它们。要启用,您需要通过 xml 或通过注解配置它们:

@Configuration
@EnableAspectJAutoProxy

通过xml:

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

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

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

更新: 在您的 testingSomethingTest 上执行 @Import (MethodExecutionAspect.class) 以确保它被组件扫描。

【讨论】:

  • 所以我按照你的建议做了(今天某个时候我也在另一个线程中看到了这个答案),并在实际记录的类上添加了这个注释。然后这个类被@Autowired 变成一个测试函数并被调用。而且......没有运气
  • @DorMunis 再一次,你把注释放在哪里了?你确定包含方面的类是共同扫描的吗?
  • @DorMunis 用于调试,将注释放在“@SpringBootApplication”或 yurr 全局配置类上。并在同一个类中创建一个方法。 "@Bean" public MethodExecutionAspect methodExecutionAspect() { return new MethodExecutionAspect()}
  • 我的错,我的意思是在方面导入。
  • 您的最后一次更新有效!我只需要想办法让@Import每次都使用MethodExecutionAspect 更容易访问,但这是一个不同的主题,而且是一个更简单的主题。非常感谢朋友!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-10-27
  • 2021-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多