在非 spring 管理的 bean 上应用方面
Apply aspect on non-spring-managed beans
在非 spring 托管 bean 上应用方面
我有一个集成测试,它调用使用 drop-wizard 框架实现的微服务 (abc-service)。我的集成测试调用微服务内的资源端点。
这个 abc-service 依赖于 2 个模块,我在 abc-service pom.xml
一个。方面模块
b。 Xyz-module --> 该模块对外部服务(不在我们的域中)进行 http 调用。
这个 xyz 模块有 15 个管理器 classes 并且每个 class 都有一个 public 静态方法,它对外部服务进行 http 调用,我想计算所有 http 调用的处理时间,即我想在所有 public 静态方法上应用 @Around advice,这在所有管理器 classes 中进行 http 调用。
xyz 模块中的所有 classes 都是非 spring 托管 beans
方面模块中的代码
package com.company.abc.operation.aspect
@Aspect
public class AppPerformanceMetricsAspect {
//@Around("execution(* com.company.product.abc.manager..*(..))") -- did'nt work
//@Around("execution(* com.company.product.abc.manager.*.*(..))") -- did'nt work
//@Pointcut("execution(* com.company.product.abc.manager.StoreDocumentManager.helloWorld(..))") -- did'nt work
// @Pointcut("within(om.company.product.abc.manager.*)") -- did'nt work
@Around("execution(* com.company.product.abc.manager.StoreDocumentManager.helloWorld())") //-- did'nt work
public Object getVaultManagerPerformanceMetrics(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("\n\n\n ########### I am here aaaaaaaaaaaa");
String packageName = proceedingJoinPoint.getSignature().getDeclaringTypeName();
String methodName = proceedingJoinPoint.getSignature().getName();
long start = System.currentTimeMillis();
Object output = proceedingJoinPoint.proceed();
long elapsedTime = System.currentTimeMillis() - start;
System.out.println("Exiting method [" + packageName + "." + methodName + "]; exec time (ms): " + elapsedTime);
return output;
}
}
微服务中的代码(abc-microservice中的一个配置class),在启动微服务时加载方面,我看到方面(AppPerformanceMetricsAspect)注册到 spring 容器,在 abc 服务(微服务)启动时捕获日志
INFO [2018-09-28 13:54:28,809] org.springframework.beans.factory.support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@14b99c84: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springConfiguration,signingStrategyFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,supportCompensatingOperationsAspect,org.springframework.context.annotation.LoadTimeWeavingConfiguration,loadTimeWeaver,org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration,org.springframework.context.config.internalBeanConfigurerAspect, AppPerformanceMetricsAspect]; root of factory hierarchy
很少有文章建议删除@EnableAspectJAutoProxy 并使用@EnableLoadTimeWeaving。
为了使 EnableLoadTimeWeaving 起作用,我使用了
VM 选项:-javaagent:C:/dev/selenium/aspectj-weaver.jar -javaagent:C:/dev/selenium/spring-instrument-4.3.3.RELEASE.jar
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED) – didn’t work
@EnableSpringConfigured – didn’t work
//@EnableAspectJAutoProxy(proxyTargetClass = true) – this didn’t work
@ComponentScan(basePackages="com.company.abc.operation.aspect")
// path to the package where my aspect is defined AppPerformanceMetricsAspect
@Configuration
public class SpringConfiguration {
@Bean
public VaultManagerPerformanceMetricsAspect vaultManagerPerformanceMetricsAspect() {
return new VaultManagerPerformanceMetricsAspect();
} // even this didn’t work
}
============================================= =================================
尝试 1:我正在尝试将您的解决方案集成到我的项目中,但它不起作用。
当我使用 VM 选项启动我的微服务时
-javaagent:C:/dev/selenium/aspectj-weaver.jar -javaagent:C:/dev/selenium/spring-instrument-4.3.3.RELEASE.jar
这是我在日志中看到的
我看到包 (com.abc.test.xyz.manager) 中的所有 classes 都被编织了
`[AppClassLoader@561279c8] debug weaving 'com.abc.test.xyz.manager.TestManager'
[AppClassLoader@561279c8] weaveinfo Join point 'method-execution(void'com.abc.test.xyz.manager.TestManager.execute())' in Type ''com.abc.test.xyz.manager.TestManager ' (TestManager.java:23) advised by around advice from 'com.test.compensating.operation.aspect.PerformanceMetricsAspect' (PerformanceMetricsAspect.java)'
但是当我尝试 运行 我的测试时
'ERROR [2018-11-30 19:15:14,435] com.abc.dropwizard.exceptionmappers.GenericExceptionMapper: Unhandled Service Error
! java.lang.NoSuchMethodError: com.test.compensating.operation.aspect.PerformanceMetricsAspect.aspectOf()Lcom/test/compensating/operation/aspect/PerformanceMetricsAspect;`
我正在 运行 使用 java 1.7 安装我的微服务
确保我的微服务项目(类似于我在之前 post 中在 github 中创建的任务列表服务项目)在 pom.xml `
中有这个条目
<build>
…
…
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14.1</version>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
</plugin>
</build>`
我的方面是在不同的模块中定义的,即
abc-compensating-operations 模块,这类似于我在之前 post 中的 github 中创建的计算指标项目
abc-compensating-operations 模块在 pom.xml
中具有以下依赖项
`<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.1</version>
</dependency>`
我检查了你的 GitHub 仓库。首先,我解压并删除了所有 ZIP 文件(提交它们非常难看,尤其是包括 target 目录内容)并添加了一个父 POM,以便能够正确构建整个项目。然后我注意到有几处不对:
如果你想通过 LTW 使用你的方面模块,你需要根据 AspectJ LTW documentation 提供正确配置的 aop.xml 文件,例如像这样:
<aspectj>
<aspects>
<aspect name="com.test.compensating.operation.aspect.PerformanceMetricsAspect"/>
</aspects>
<weaver options="-verbose -showWeaveInfo">
<include within="com.test..*"/>
</weaver>
</aspectj>
此外,你的切入点是错误的:
@Around("execution(* com.test.manager.performOperation())")
相反,它应该是(请注意 ..
符号):
@Around("execution(* com.test.manager..performOperation())")
现在您可以从 IDE 运行 您的主要 class 并在启动期间查看以下日志输出:
[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.9.1 built on Friday Apr 20, 2018 at 16:47:33 GMT
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_Spring_ApplyOnNonSpring/calculate-metrics/target/classes/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect com.test.compensating.operation.aspect.PerformanceMetricsAspect
[AppClassLoader@18b4aac2] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
(...)
INFO [2018-11-05 11:23:03,317] org.eclipse.jetty.server.ServerConnector: Started application@7249dadf{HTTP/1.1}{0.0.0.0:8080}
INFO [2018-11-05 11:23:03,321] org.eclipse.jetty.server.ServerConnector: Started admin@4362d7df{HTTP/1.1}{0.0.0.0:8081}
INFO [2018-11-05 11:23:03,322] org.eclipse.jetty.server.Server: Started @4168ms
如果您访问 http://localhost:8080/task-list,您还会看到该方面有效:
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void com.test.manager.AdditionManager.performOperation())' in Type 'com.test.manager.AdditionManager' (AdditionManager.java:16) advised by around advice from 'com.test.compensating.operation.aspect.PerformanceMetricsAspect' (PerformanceMetricsAspect.java)
########### I am here aaaaaaaaaaaa
Adding 2 numbers 1 2 = 12
Exiting method [com.test.manager.AdditionManager.performOperation]; exec time (ms): 0
0:0:0:0:0:0:0:1 - - [05/Nov/2018:11:23:12 +0000] "GET /task-list HTTP/1.1" 200 23 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36" 251
此外,您的 uber JAR 也配置不正确,即应用程序在从 uber JAR 启动时抛出错误。以前从未使用过 Dropwizard,我用谷歌搜索然后修复了它 like this。
我为你创建了一个forked repo branch and a pull request。享受吧!
在非 spring 托管 bean 上应用方面
我有一个集成测试,它调用使用 drop-wizard 框架实现的微服务 (abc-service)。我的集成测试调用微服务内的资源端点。 这个 abc-service 依赖于 2 个模块,我在 abc-service pom.xml
一个。方面模块
b。 Xyz-module --> 该模块对外部服务(不在我们的域中)进行 http 调用。 这个 xyz 模块有 15 个管理器 classes 并且每个 class 都有一个 public 静态方法,它对外部服务进行 http 调用,我想计算所有 http 调用的处理时间,即我想在所有 public 静态方法上应用 @Around advice,这在所有管理器 classes 中进行 http 调用。 xyz 模块中的所有 classes 都是非 spring 托管 beans
方面模块中的代码
package com.company.abc.operation.aspect
@Aspect
public class AppPerformanceMetricsAspect {
//@Around("execution(* com.company.product.abc.manager..*(..))") -- did'nt work
//@Around("execution(* com.company.product.abc.manager.*.*(..))") -- did'nt work
//@Pointcut("execution(* com.company.product.abc.manager.StoreDocumentManager.helloWorld(..))") -- did'nt work
// @Pointcut("within(om.company.product.abc.manager.*)") -- did'nt work
@Around("execution(* com.company.product.abc.manager.StoreDocumentManager.helloWorld())") //-- did'nt work
public Object getVaultManagerPerformanceMetrics(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("\n\n\n ########### I am here aaaaaaaaaaaa");
String packageName = proceedingJoinPoint.getSignature().getDeclaringTypeName();
String methodName = proceedingJoinPoint.getSignature().getName();
long start = System.currentTimeMillis();
Object output = proceedingJoinPoint.proceed();
long elapsedTime = System.currentTimeMillis() - start;
System.out.println("Exiting method [" + packageName + "." + methodName + "]; exec time (ms): " + elapsedTime);
return output;
}
}
微服务中的代码(abc-microservice中的一个配置class),在启动微服务时加载方面,我看到方面(AppPerformanceMetricsAspect)注册到 spring 容器,在 abc 服务(微服务)启动时捕获日志
INFO [2018-09-28 13:54:28,809] org.springframework.beans.factory.support.DefaultListableBeanFactory: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@14b99c84: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,springConfiguration,signingStrategyFactory,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,supportCompensatingOperationsAspect,org.springframework.context.annotation.LoadTimeWeavingConfiguration,loadTimeWeaver,org.springframework.context.annotation.aspectj.SpringConfiguredConfiguration,org.springframework.context.config.internalBeanConfigurerAspect, AppPerformanceMetricsAspect]; root of factory hierarchy
很少有文章建议删除@EnableAspectJAutoProxy 并使用@EnableLoadTimeWeaving。 为了使 EnableLoadTimeWeaving 起作用,我使用了
VM 选项:-javaagent:C:/dev/selenium/aspectj-weaver.jar -javaagent:C:/dev/selenium/spring-instrument-4.3.3.RELEASE.jar
@EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED) – didn’t work
@EnableSpringConfigured – didn’t work
//@EnableAspectJAutoProxy(proxyTargetClass = true) – this didn’t work
@ComponentScan(basePackages="com.company.abc.operation.aspect")
// path to the package where my aspect is defined AppPerformanceMetricsAspect
@Configuration
public class SpringConfiguration {
@Bean
public VaultManagerPerformanceMetricsAspect vaultManagerPerformanceMetricsAspect() {
return new VaultManagerPerformanceMetricsAspect();
} // even this didn’t work
}
============================================= ================================= 尝试 1:我正在尝试将您的解决方案集成到我的项目中,但它不起作用。 当我使用 VM 选项启动我的微服务时
-javaagent:C:/dev/selenium/aspectj-weaver.jar -javaagent:C:/dev/selenium/spring-instrument-4.3.3.RELEASE.jar
这是我在日志中看到的
我看到包 (com.abc.test.xyz.manager) 中的所有 classes 都被编织了
`[AppClassLoader@561279c8] debug weaving 'com.abc.test.xyz.manager.TestManager'
[AppClassLoader@561279c8] weaveinfo Join point 'method-execution(void'com.abc.test.xyz.manager.TestManager.execute())' in Type ''com.abc.test.xyz.manager.TestManager ' (TestManager.java:23) advised by around advice from 'com.test.compensating.operation.aspect.PerformanceMetricsAspect' (PerformanceMetricsAspect.java)'
但是当我尝试 运行 我的测试时
'ERROR [2018-11-30 19:15:14,435] com.abc.dropwizard.exceptionmappers.GenericExceptionMapper: Unhandled Service Error
! java.lang.NoSuchMethodError: com.test.compensating.operation.aspect.PerformanceMetricsAspect.aspectOf()Lcom/test/compensating/operation/aspect/PerformanceMetricsAspect;`
我正在 运行 使用 java 1.7 安装我的微服务 确保我的微服务项目(类似于我在之前 post 中在 github 中创建的任务列表服务项目)在 pom.xml `
中有这个条目<build>
…
…
<plugin>
<groupId>com.jcabi</groupId>
<artifactId>jcabi-maven-plugin</artifactId>
<version>0.14.1</version>
<executions>
<execution>
<goals>
<goal>ajc</goal>
</goals>
</execution>
</executions>
</plugin>
</build>`
我的方面是在不同的模块中定义的,即 abc-compensating-operations 模块,这类似于我在之前 post 中的 github 中创建的计算指标项目 abc-compensating-operations 模块在 pom.xml
中具有以下依赖项`<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.1</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>1.9.1</version>
</dependency>`
我检查了你的 GitHub 仓库。首先,我解压并删除了所有 ZIP 文件(提交它们非常难看,尤其是包括 target 目录内容)并添加了一个父 POM,以便能够正确构建整个项目。然后我注意到有几处不对:
如果你想通过 LTW 使用你的方面模块,你需要根据 AspectJ LTW documentation 提供正确配置的 aop.xml 文件,例如像这样:
<aspectj>
<aspects>
<aspect name="com.test.compensating.operation.aspect.PerformanceMetricsAspect"/>
</aspects>
<weaver options="-verbose -showWeaveInfo">
<include within="com.test..*"/>
</weaver>
</aspectj>
此外,你的切入点是错误的:
@Around("execution(* com.test.manager.performOperation())")
相反,它应该是(请注意 ..
符号):
@Around("execution(* com.test.manager..performOperation())")
现在您可以从 IDE 运行 您的主要 class 并在启动期间查看以下日志输出:
[AppClassLoader@18b4aac2] info AspectJ Weaver Version 1.9.1 built on Friday Apr 20, 2018 at 16:47:33 GMT
[AppClassLoader@18b4aac2] info register classloader sun.misc.Launcher$AppClassLoader@18b4aac2
[AppClassLoader@18b4aac2] info using configuration /C:/Users/alexa/Documents/java-src/SO_AJ_Spring_ApplyOnNonSpring/calculate-metrics/target/classes/META-INF/aop.xml
[AppClassLoader@18b4aac2] info register aspect com.test.compensating.operation.aspect.PerformanceMetricsAspect
[AppClassLoader@18b4aac2] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
(...)
INFO [2018-11-05 11:23:03,317] org.eclipse.jetty.server.ServerConnector: Started application@7249dadf{HTTP/1.1}{0.0.0.0:8080}
INFO [2018-11-05 11:23:03,321] org.eclipse.jetty.server.ServerConnector: Started admin@4362d7df{HTTP/1.1}{0.0.0.0:8081}
INFO [2018-11-05 11:23:03,322] org.eclipse.jetty.server.Server: Started @4168ms
如果您访问 http://localhost:8080/task-list,您还会看到该方面有效:
[AppClassLoader@18b4aac2] weaveinfo Join point 'method-execution(void com.test.manager.AdditionManager.performOperation())' in Type 'com.test.manager.AdditionManager' (AdditionManager.java:16) advised by around advice from 'com.test.compensating.operation.aspect.PerformanceMetricsAspect' (PerformanceMetricsAspect.java)
########### I am here aaaaaaaaaaaa
Adding 2 numbers 1 2 = 12
Exiting method [com.test.manager.AdditionManager.performOperation]; exec time (ms): 0
0:0:0:0:0:0:0:1 - - [05/Nov/2018:11:23:12 +0000] "GET /task-list HTTP/1.1" 200 23 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36" 251
此外,您的 uber JAR 也配置不正确,即应用程序在从 uber JAR 启动时抛出错误。以前从未使用过 Dropwizard,我用谷歌搜索然后修复了它 like this。
我为你创建了一个forked repo branch and a pull request。享受吧!