2016-08-14 2 views
7

Ich versuche, einen Timer-Aspekt für die Messung Methodenlaufzeit zu erstellen.Aspekt funktioniert nicht mit Spring Boot-Anwendung mit externen jar

Ich habe eine Anmerkung @Timer genannt:

@Retention(RetentionPolicy.RUNTIME) 
@Target(value = {ElementType.METHOD, ElementType.TYPE}) 
public @interface Timer { 
    String value(); 
} 

Und dann habe ich den Aspekt wie folgt:

@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; 
    } 

ich eine Konfigurationsklasse haben wie folgt:

@Configuration 
@EnableAspectJAutoProxy 
public class MetricsConfiguration { 

    @Bean 
    public MetricAspect notifyAspect() { 
     return new MetricAspect(); 
    } 
} 

Alles bis hier ist in einem abgepackten Glas definiert, das Ich benutze als Abhängigkeit in meiner Feder Boot-Anwendung

In meiner Feder Boot-Anwendung importieren ich die MetricsConfiguration und ich gedebuggt den Code und sah, dass die MetricAspect Bean erstellt wird.

ich es im Code wie folgt verwenden:

@Service 
public class MyService { 
    ... 

    @Timer("mymetric") 
    public void foo() { 
     // Some code here... 
    } 

    ... 
} 

Aber mein Code nicht erreicht zum measure Verfahren. Nicht sicher, was ich vermisse.

Für das Bild vervollständigt, ich habe diese Abhängigkeiten in meiner pom-Datei hinzugefügt:

<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> 

Das ist die @Configuration Klasse ist, die MetricsConfiguration importiert:

@Configuration 
@EnableAspectJAutoProxy 
@Import(MetricsConfiguration.class) 
@PropertySource("classpath:application.properties") 
public class ApplicationConfiguration { 

} 

Es ist geladen mit Spring automagically Konfiguration Laden.

+0

Haben Sie auch feder Aspekte Abhängigkeit haben? –

+0

Ich habe versucht, es hinzuzufügen, und es hat nicht so gut funktioniert:/ – Avi

+0

Warum verwenden Sie Reflexion, um die Anmerkung zu erhalten? Sie können es einfach zu den Parametern der Around-Methode hinzufügen und direkt darauf zugreifen. – sheltem

Antwort

4

kann @Component oder @Configurable Ihr Problem lösen?

@Aspect 
@Component 
public class yourAspect { 
... 
} 

Enable Spring AOP or AspectJ

EDIT:

ich ein Projekt erstellt, um Ihre Frage zu simulieren, scheint doch kein Problem. Ist es von anderen Problemen betroffen?

https://github.com/zerg000000/spring-aspectj-test

+0

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-aop offizielles Beispiel für die Verwendung von AspectJ im Frühjahr boot –

+0

Danke für Ihre Antwort Albert . Es ist jedoch nicht das '@ Component' Problem. Ich habe versucht, das Wesentliche davon, aber ich erstelle die Bohne in 'MetricsConfiguration' sowieso. Es ist nicht das Problem. Ich vermute, das liegt daran, dass der Aspekt und die Bohne in einem externen Gefäß sind und ich Springfeder benutze. – Avi

1

Ich war nicht in der Lage, Ihr Problem aspectj 1.8.8 und Feder 4.2.5 mit zu reproduzieren. Here ist meine Maven Multi-Modul-Ansatz mit Aspekt in separaten Glas.

Ich habe Ihren Code leicht geändert, aber keine Anmerkungen geändert. Das einzige, was sich unterscheiden werden könnte, ist, dass ich org.springframework:spring-aop Abhängigkeit und definiert meine Einstiegspunkt hinzugefügt haben, wie folgt:

@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(); 
    } 
} 
+0

Danke für Ihre gründliche Antwort. Ich konnte immer noch keinen Unterschied zwischen meinem und deinem Code finden. Meine Vermutung ist, dass es mit der Tatsache zusammenhängt, dass der Frühling automatisch eine '@ Konfiguration' Klasse (eigentlich mehr als eine) lädt und etwas dort verloren geht. Ich werde weiter graben. – Avi

+0

@Avi können Sie zeigen, wie importieren Sie 'MetricsConfiguration' in Ihrer Anwendung? Weicht es von meinem Beispiel ab? – vsminkov

+0

Ja, ich habe die Frage aktualisiert - am Ende hinzugefügt. – Avi

Verwandte Themen