Spring 在不同项目中用作已编译的 jar 时,AOP 不工作
Spring AOP not working when using as a compiled jar in a different project
我有一个可用的 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();
}
}
要使这些方面起作用,您需要启用它们。要启用您需要通过 xml 或注释配置它们:
@Configuration
@EnableAspectJAutoProxy
通过xml:
<beans …>
<!– Enable AspectJ auto-wiring –>
<aop:aspectj-autoproxy />
</beans>
当您将 jar 包含到另一个应用程序中时,该其他应用程序有其自己的配置和上下文。即使您已经为您的原始上下文启用了方面自动装配,您仍然需要通过上面指出的两种方式之一为您的新应用程序执行相同的操作。
如果您使用注释,请确保它在组件扫描范围内,并且它实际上包含在您的上下文中。
更新:
在您的 testingSomethingTest 上执行 @Import (MethodExecutionAspect.class)
以确保它是组件扫描的。
我有一个可用的 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();
}
}
要使这些方面起作用,您需要启用它们。要启用您需要通过 xml 或注释配置它们:
@Configuration
@EnableAspectJAutoProxy
通过xml:
<beans …>
<!– Enable AspectJ auto-wiring –>
<aop:aspectj-autoproxy />
</beans>
当您将 jar 包含到另一个应用程序中时,该其他应用程序有其自己的配置和上下文。即使您已经为您的原始上下文启用了方面自动装配,您仍然需要通过上面指出的两种方式之一为您的新应用程序执行相同的操作。
如果您使用注释,请确保它在组件扫描范围内,并且它实际上包含在您的上下文中。
更新:
在您的 testingSomethingTest 上执行 @Import (MethodExecutionAspect.class)
以确保它是组件扫描的。