J'essaie de créer un aspect de minuterie pour mesurer le temps d'exécution des méthodes.
J'ai créé une annotation nommée @Timer
:
@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
public @interface Timer {
String value();
}
Et puis j'ai créé l'aspect comme suit:
@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;
}
J'ai une classe de configuration comme suit:
@Configuration
@EnableAspectJAutoProxy
public class MetricsConfiguration {
@Bean
public MetricAspect notifyAspect() {
return new MetricAspect();
}
}
Jusqu'à présent, tout est défini dans un fichier jar emballé que j'utilise comme dépendance dans mon application Spring Boot
Dans mon application de démarrage printanière, j'importe la variable MetricsConfiguration
, j'ai débogué le code et constaté que le bean MetricAspect
est créé.
Je l'utilise dans le code comme suit:
@Service
public class MyService {
...
@Timer("mymetric")
public void foo() {
// Some code here...
}
...
}
Mais mon code n'atteint pas la méthode measure
. Pas sûr de ce que je manque.
Pour compléter la photo, j'ai ajouté ces dépendances dans mon fichier 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>
C'est la classe @Configuration
qui importe MetricsConfiguration
:
@Configuration
@EnableAspectJAutoProxy
@Import(MetricsConfiguration.class)
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {
}
Il est chargé avec le chargement de configuration automagique de Spring.
@Component
ou @Configurable
peut-il résoudre votre problème?
@Aspect
@Component
public class yourAspect {
...
}
MODIFIER:
J'ai créé un projet pour simuler votre problème, ne semble pas être un problème après tout. Est-ce affecté par un autre problème?
J'ai eu un problème similaire où l'aspect a été construit dans une bibliothèque de jar, et l'application Spring-Boot était ailleurs. Il s'avère que les packages de l'application Spring-Boot et de la bibliothèque JAR étaient différents. En raison de quoi Spring n’examinait pas le paquet de la bibliothèque pour s’insérer automatiquement dans le contexte de l’application.
Donc, il fallait inclure @ComponentScan({"base.package.application.*", "base.package.library.*"})
dans Application.Java
Je n'ai pas pu reproduire votre problème avec aspectJ 1.8.8 et spring 4.2.5 . Ici est mon approche multi-module maven avec un aspect dans un bocal séparé.
J'ai légèrement modifié votre code mais je n'ai pas changé les annotations. La seule chose qui peut différer est que j'ai ajouté la dépendance org.springframework:spring-aop
et défini mon point d'entrée comme suit:
@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) config dans spring.factories
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
a.b.c.MyAutoConfiguration