在非 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。享受吧!