Java Aspect不适用于带有外部jar的Spring引导应用程序
我试图创建一个计时器方面来测量方法的运行时间 我创建了一个名为Java Aspect不适用于带有外部jar的Spring引导应用程序,java,spring,aop,aspectj,Java,Spring,Aop,Aspectj,我试图创建一个计时器方面来测量方法的运行时间 我创建了一个名为@Timer的注释: @Retention(RetentionPolicy.RUNTIME) @Target(value = {ElementType.METHOD, ElementType.TYPE}) public @interface Timer { String value(); } 然后我创建了如下方面: @Aspect public class MetricAspect { @Autowired
@Timer
的注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
public @interface Timer {
String value();
}
然后我创建了如下方面:
@Aspect
public class MetricAspect {
@Autowired
private MetricsFactory metricsFactory;
@Pointcut("@annotation(my.package.Timer)")
public void timerPointcut() {}
@Around("timerPointcut() ")
public Object measure(ProceedingJoinPoint joinPoint) throws Throwable {
/* Aspect logic here */
}
private Timer getClassAnnotation(MethodSignature methodSignature) {
Timer annotation;
Class<?> clazz = methodSignature.getDeclaringType();
annotation = clazz.getAnnotation(Timer.class);
return annotation;
}
@Configuration
@EnableAspectJAutoProxy
public class MetricsConfiguration {
@Bean
public MetricAspect notifyAspect() {
return new MetricAspect();
}
}
@Service
public class MyService {
...
@Timer("mymetric")
public void foo() {
// Some code here...
}
...
}
在此之前的所有内容都是在打包的jar中定义的,我在spring引导应用程序中将其作为依赖项使用
在我的spring boot应用程序中,我导入了MetricsConfiguration
,并调试了代码,发现创建了MetricAspect
bean
我在代码中使用它,如下所示:
@Aspect
public class MetricAspect {
@Autowired
private MetricsFactory metricsFactory;
@Pointcut("@annotation(my.package.Timer)")
public void timerPointcut() {}
@Around("timerPointcut() ")
public Object measure(ProceedingJoinPoint joinPoint) throws Throwable {
/* Aspect logic here */
}
private Timer getClassAnnotation(MethodSignature methodSignature) {
Timer annotation;
Class<?> clazz = methodSignature.getDeclaringType();
annotation = clazz.getAnnotation(Timer.class);
return annotation;
}
@Configuration
@EnableAspectJAutoProxy
public class MetricsConfiguration {
@Bean
public MetricAspect notifyAspect() {
return new MetricAspect();
}
}
@Service
public class MyService {
...
@Timer("mymetric")
public void foo() {
// Some code here...
}
...
}
但是我的代码没有达到measure
方法。不知道我错过了什么
为了完成图片,我在pom文件中添加了以下依赖项:
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.7.4</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.7.4</version>
</dependency>
</dependencies>
它加载了Spring的自动配置加载。可以
@Component
或@Configurable
解决您的问题吗
@Aspect
@Component
public class yourAspect {
...
}
编辑:
我创建了一个项目来模拟您的问题,似乎根本没有问题。是否受到其他问题的影响
我无法使用aspectJ 1.8.8和spring 4.2.5重现您的问题。是我的maven多模块方法,在单独的jar中包含方面 我稍微修改了您的代码,但没有更改任何注释。唯一不同的是,我添加了
org.springframework:springaop
依赖项,并将我的入口点定义如下:
@Aspect
public class MetricAspect {
@Autowired
private MetricsFactory metricsFactory;
@Pointcut("@annotation(my.package.Timer)")
public void timerPointcut() {}
@Around("timerPointcut() ")
public Object measure(ProceedingJoinPoint joinPoint) throws Throwable {
/* Aspect logic here */
}
private Timer getClassAnnotation(MethodSignature methodSignature) {
Timer annotation;
Class<?> clazz = methodSignature.getDeclaringType();
annotation = clazz.getAnnotation(Timer.class);
return annotation;
}
@Configuration
@EnableAspectJAutoProxy
public class MetricsConfiguration {
@Bean
public MetricAspect notifyAspect() {
return new MetricAspect();
}
}
@Service
public class MyService {
...
@Timer("mymetric")
public void foo() {
// Some code here...
}
...
}
@Import(MetricsConfiguration.class)
@SpringBoot应用程序
公共类应用程序{
//@Bean定义在这里//
公共静态void main(字符串[]args)引发InterruptedException{
ApplicationContext ctx=
SpringApplication.run(Application.class,args);
getBean(MyService.class).doWork();
}
}
我遇到了一个类似的问题,方面构建在jar库中,而spring启动应用程序则在其他地方。原来spring启动应用程序和jar库的包是不同的。因此,Spring没有查看库的包以自动连接到应用程序上下文中
因此,必须在application.java中包含@ComponentScan({“base.package.application.*”,“base.package.library.*})
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
a.b.c.MyAutoConfiguration
添加此组件扫描以解决此问题
@ComponentScan("package.of.aspect")
@Configuration
@EnableAspectJAutoProxy
@Import(MetricsConfiguration.class)
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {
}
根据解释,您必须将如下构建设置添加到实现方面接口的所有类中
<build>
<plugins>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>aspectj-maven-plugin</artifactId>
<version>1.11</version>
<configuration>
<complianceLevel>1.8</complianceLevel>
<includes>
<include>**/*.java</include>
<include>**/*.aj</include>
</includes>
<aspectDirectory>src/main/aspect</aspectDirectory>
<testAspectDirectory>src/test/aspect</testAspectDirectory>
<XaddSerialVersionUID>true</XaddSerialVersionUID>
<showWeaveInfo>true</showWeaveInfo>
<aspectLibraries>
<aspectLibrary>
<groupId>your aspect groupId</groupId>
<artifactId>your aspect artifactId</artifactId>
</aspectLibrary>
</aspectLibraries>
</configuration>
<executions>
<execution>
<id>compile_with_aspectj</id>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile_with_aspectj</id>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjtools</artifactId>
<version>${aspectj.runtime.version}</version>
</dependency>
<dependency>
<groupId>your aspect groupId</groupId>
<artifactId>youar aspect artifactId</artifactId>
<version>1.0.0-SNAPSHOT</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
org.codehaus.mojo
aspectj maven插件
1.11
1.8
**/*.爪哇
**/*.aj
src/main/aspect
src/测试/方面
真的
真的
您的aspect groupId
你的方面人工智能
使用_aspectj编译_
编译
用aspectj测试编译
测试编译
org.aspectj
aspectjtools
${aspectj.runtime.version}
您的aspect groupId
youar aspect artifactId
1.0.0-SNAPSHOT
在切入点本身出现问题时调试spring boot Aspectj特性即使有详细的日志记录也不容易:
不幸的是,带注释的spring boot+spring aop没有很多方法来调试方面,并且为什么一些类,特别是非spring组件jar类,没有被扫描,例如jar类或静态final方法,需要正确的切入点来覆盖所有类/实现,即使它们是组件扫描的
调试Asepct(或使用核心AOP和避免spring AOP)的最佳方法是使用LTW aspectj weaver,使用org/aspectj/AOP.xml或META-INF/AOP.xml启用AOP.xml和配置控制
-verbose=true-javaagent:~/.m2/repository/org/aspectj/aspectjweaver/1.9.5/aspectjweaver-1.9.5.jar
要使用调试/详细日志调试所有方面/类,以查看未扫描某些类的原因,请执行以下操作:
这几乎总是有助于找出切入点或类未被选中的问题
或者,只需使用LTW aop,请参见,您是否也有spring方面的依赖关系?我尝试添加它,但效果不好:/n为什么要使用反射来获取注释?您可以简单地将它添加到around advice方法的参数中,并直接访问它。@kriegaex-事实上,我在过去多次创建过这种代码,并且成功了。主要区别在于我提到的spring boot的使用:/is
timerPointcut()
方法被调用了吗?关于如何在spring BootJ中使用AspectJ的官方示例感谢您的回答。但这不是@组件的问题。我试图了解它的要点,但我还是在MetricsConfiguration
中创建了bean。这不是问题所在。我怀疑这是因为方面和bean在一个外部jar中,我使用的是spring boot。添加@Component注释解决了这个问题,而且它也有意义,因为方面可能需要在运行时注入,有什么想法吗?谢谢你的全面回答。我仍然找不到我的代码和你的代码之间的差异。我猜