AspectJ LTW无法在非托管类上使用Spring Boot

时间:2016-04-08 18:35:02

标签: spring spring-boot aspectj spring-aop load-time-weaving

我在使用SpringBoot和AspectJ进行日志记录的大型应用程序上遇到问题。日志记录适用于Spring Beans,但不适用于非托管类(我使用'new'实例化的类)。

我已经创建了一个示例应用,您可以在其中看到发生的问题,您可以在此处访问它:

https://bitbucket.org/tomkro/stack_question

应用程序非常简单,Gradle文件与标准的Spring Boot启动程序相同。

这里有5个相关课程。

Application.java,它是主类:

@EnableAspectJAutoProxy
@EnableLoadTimeWeaving(aspectjWeaving= EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
@SpringBootApplication(scanBasePackages = "com.test.*")
public class Application {

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

AspectConfig文件(为简单起见,还定义了RestController,可以很容易地分隔文件)

@RestController
@Configuration
@ComponentScan(basePackages = {"com.test"})
public class AspectConfig {

    @Bean
    public TestLogger testLogger(){
        return new TestLogger();
    }

    @Autowired
    TestClass testClass;

    @RequestMapping("/")
    public int get() {
        return testClass.methodFromClass1();
    }

}

TestLogger,它定义了这个应用程序的方面:

@Aspect
public class TestLogger {

    public TestLogger() {
    }

    @Around("execution( * com.test.classes..*.*(..))")
    public Object aroundExecution(ProceedingJoinPoint pjp) throws Throwable {
        String packageName = pjp.getSignature().getDeclaringTypeName();
        String methodName = pjp.getSignature().getName();
        long start = System.currentTimeMillis();

        System.out.println(packageName + "." + methodName + " - Starting execution ");

        Object output = pjp.proceed();
        Long elapsedTime = System.currentTimeMillis() - start;

        System.out.println(packageName + "." + methodName + " - Ending execution ["+elapsedTime+" ms]");
        return output;
    }

}

然后有两个文件,一个由Spring管理,另一个不是:

TestClass1:

@Component
public class TestClass {

    public int methodFromClass1() {
        TestClass2 test = new TestClass2();
        return test.methodFromClass2();
    }

}

TestClass2

public class TestClass2 {
    public int methodFromClass2() {
        int a = 10;
        int b = 5;

        return b + a;
    }
}

还有META-INF中的aop.xml文件,它指定了Aspect

<!DOCTYPE aspectj PUBLIC "-//AspectJ//DTD//EN" "http://www.eclipse.org/aspectj/dtd/aspectj.dtd">
<aspectj>
    <weaver option="-debug">
        <!-- only weave classes in our application-specific packages -->
        <include within="com.test.*"/>
    </weaver>

    <aspects>
        <!-- weave in just this aspect -->
        <aspect name="com.test.utilities.TestLogger"/>
    </aspects>

</aspectj>

我使用Spring文档here上的教程跟踪了这个版本的大部分内容,现在我已经摸不着头脑了两天,我无法弄清楚发生了什么。托管Bean记录正常,但未管理的Bean未记录。

我正在使用项目中包含的run.bat来启动,基本上它是这样做的:

call gradle build
java -javaagent:.\src\main\resources\aspectjweaver.jar -javaagent:.\src\main\resources\spring-instrument.jar -jar build\libs\Test-0.0.1-SNAPSHOT.jar

这两个罐子都是最新的。通常你只需要JAR,但我看到有人同时使用JAR,并给了它一个机会。这是启动和执行“localhost:8080”

调用后的输出
[LaunchedURLClassLoader@6d8a00e3] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.3.0.RELEASE)

2016-04-08 15:21:44.116  INFO 20400 --- [           main] com.test.Application                     : Starting Application on PC000BR23205 with PID 20400 (C:\git\Test\build\libs\Test-0.0.1-SNAPSHOT.jar started by tkroth in C:\git\T
est)
2016-04-08 15:21:44.120  INFO 20400 --- [           main] com.test.Application                     : No profiles are active
2016-04-08 15:21:44.294  INFO 20400 --- [           main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2cd72cea: startup date [Fri Ap
r 08 15:21:44 BRT 2016]; root of context hierarchy
2016-04-08 15:21:44.950  INFO 20400 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Overriding bean definition for bean 'beanNameViewResolver' with a different definition: replacing [Root bean: class [null]; scope
=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration; fa
ctoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/ErrorMvcAutoConfiguration$WhitelabelErrorViewConfiguration.class]]
 with [Root bean: class [null]; scope=; abstract=false; lazyInit=false; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration$W
ebMvcAutoConfigurationAdapter; factoryMethodName=beanNameViewResolver; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [org/springframework/boot/autoconfigure/web/WebMvcAutoConfiguration$WebMvcAut
oConfigurationAdapter.class]]
2016-04-08 15:21:45.872  INFO 20400 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2016-04-08 15:21:45.888  INFO 20400 --- [           main] o.apache.catalina.core.StandardService   : Starting service Tomcat
2016-04-08 15:21:45.891  INFO 20400 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.0.28
2016-04-08 15:21:45.987  INFO 20400 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2016-04-08 15:21:45.987  INFO 20400 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1695 ms
2016-04-08 15:21:46.342  INFO 20400 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2016-04-08 15:21:46.347  INFO 20400 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'characterEncodingFilter' to: [/*]
2016-04-08 15:21:46.348  INFO 20400 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2016-04-08 15:21:46.349  INFO 20400 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2016-04-08 15:21:46.349  INFO 20400 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'requestContextFilter' to: [/*]
2016-04-08 15:21:46.439  INFO 20400 --- [           main] o.s.c.w.DefaultContextLoadTimeWeaver     : Found Spring's JVM agent for instrumentation
2016-04-08 15:21:46.455  INFO 20400 --- [           main] o.s.c.w.DefaultContextLoadTimeWeaver     : Found Spring's JVM agent for instrumentation
[LaunchedURLClassLoader@6d8a00e3] warning javax.* types are not being woven because the weaver option '-Xset:weaveJavaxPackages=true' has not been specified
2016-04-08 15:21:46.781  INFO 20400 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@2cd72cea:
startup date [Fri Apr 08 15:21:44 BRT 2016]; root of context hierarchy
2016-04-08 15:21:46.874  INFO 20400 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/]}" onto public int com.test.configuration.AspectConfig.get()
2016-04-08 15:21:46.877  INFO 20400 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.sp
ringframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2016-04-08 15:21:46.878  INFO 20400 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoco
nfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest)
2016-04-08 15:21:46.912  INFO 20400 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-04-08 15:21:46.912  INFO 20400 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2016-04-08 15:21:47.030  INFO 20400 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler
]
2016-04-08 15:21:47.133  INFO 20400 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2016-04-08 15:21:47.204  INFO 20400 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2016-04-08 15:21:47.210  INFO 20400 --- [           main] com.test.Application                     : Started Application in 3.481 seconds (JVM running for 4.306)
2016-04-08 15:21:51.680  INFO 20400 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring FrameworkServlet 'dispatcherServlet'
2016-04-08 15:21:51.680  INFO 20400 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization started
2016-04-08 15:21:51.704  INFO 20400 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : FrameworkServlet 'dispatcherServlet': initialization completed in 23 ms
com.test.classes.TestClass.methodFromClass1 - Starting execution
com.test.classes.TestClass.methodFromClass1 - Ending execution [15 ms]

正如您所看到的,TestClass2永远不会被记录,尽管它被调用。我在这里缺少什么?

真正的问题是,如何在SpringBoot环境中使LTW处理非bean?随意在我上面提供的存储库上提交更改。

0 个答案:

没有答案