メソッドの実行時間を測定するためのタイマーアスペクトを作成しようとしています。
@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();
}
}
ここまでのすべては、スプリングブートアプリケーションで依存関係として使用するパッケージ化されたjarで定義されています
私のスプリングブートアプリケーションでMetricsConfiguration
をインポートし、コードをデバッグしてMetricAspect
Beanが作成されたことを確認しました。
次のようにコードで使用します。
@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>
これがMetricsConfiguration
をインポートする@Configuration
クラスです。
@Configuration
@EnableAspectJAutoProxy
@Import(MetricsConfiguration.class)
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {
}
これは、Springの自動設定ロードでロードされます。
できる @Component
または@Configurable
問題を解決しますか?
@Aspect
@Component
public class yourAspect {
...
}
編集:
あなたの問題をシミュレートするプロジェクトを作成しましたが、結局問題ないようです。他の問題の影響を受けますか?
aspectJ 1.8.8およびspring 4.2.5を使用して問題を再現できませんでした。 ここ は、別のjarにアスペクトを持つ私のmavenマルチモジュールアプローチです。
コードを少し変更しましたが、アノテーションは変更しませんでした。異なる可能性があるのは、org.springframework:spring-aop
依存関係を追加し、エントリポイントを次のように定義したことだけです。
@Import(MetricsConfiguration.class)
@SpringBootApplication
public class Application {
// @Bean definitions here //
public static void main(String[] args) throws InterruptedException {
ApplicationContext ctx =
SpringApplication.run(Application.class, args);
ctx.getBean(MyService.class).doWork();
}
}
(1)
@Aspect
public class MyAspect {
//....
}
(2)
package a.b.c
@Configuration
public class MyAutoConfiguration {
@Bean
MyAspect myAspect() {
return new MyAspect();
}
}
(3)spring.factoriesのconfig
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
a.b.c.MyAutoConfiguration
アスペクトがjarライブラリに構築されている場合も同様の問題があり、Spring-Bootアプリケーションが別の場所にありました。 Spring-Bootアプリケーションとjarライブラリのパッケージが異なることがわかりました。 Springがライブラリのパッケージを調べて、アプリケーションコンテキストに自動配線していなかったためです。
したがって、Application.Javaに@ComponentScan({"base.package.application.*", "base.package.library.*"})
を含める必要がありました。
このコンポーネントを追加して問題を解決してください。
@ComponentScan("package.of.aspect")
@Configuration
@EnableAspectJAutoProxy
@Import(MetricsConfiguration.class)
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {
}