2016-08-14 9 views
7

Я пытаюсь создать аспект таймера для измерения времени выполнения методов.Aspect не работает с приложением Spring boot с внешним банком

Я создал аннотацию с именем @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(); 
    } 
} 

Все до тех пор, пока здесь не определено в упакованном банке, который Я использую в качестве зависимости в моем весеннем приложении загрузки

В моей весной загрузки приложения я импортировать MetricsConfiguration и я отлаживается код и увидел, что MetricAspect компонент создается.

Я использую его в коде следующим образом:

@Service 
public class MyService { 
    ... 

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

    ... 
} 

Но мой код не доходит до метода measure. Не уверен, что мне не хватает.

Для завершения картины, у меня есть эта зависимость в моем файле п добавил:

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

Это @Configuration класса, который импортирует MetricsConfiguration:

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

} 

Это загружено автомагический конфигурации загрузки в Spring.

+0

У вас также есть весна-аспекты зависимость? –

+0

Я попытался добавить его, и он тоже не сработал:/ – Avi

+0

Почему вы используете отражение, чтобы получить аннотацию? Вы можете просто добавить его к параметрам метода консультаций и получить доступ к нему напрямую. – sheltem

ответ

4

может @Component или @Configurable решить вашу проблему?

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

Enable Spring AOP or AspectJ

EDIT:

Я создал проект для имитации вашего вопроса, кажется, не проблемы в конце концов. На него влияет другая проблема?

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

+0

https://github.com/spring-projects/spring-boot/tree/master/spring-boot-samples/spring-boot-sample-aop официальный пример использования AspectJ в весенней загрузке –

+0

Спасибо за ваш ответ Альберт , Однако это не проблема '@ Component'. Я попытался понять суть этого, но я все равно создаю компонент в MetricsConfiguration. Это не проблема. Я подозреваю, что это потому, что аспект и фасоль находятся во внешней банке, и я использую весенний ботинок. – Avi

1

Я не смог воспроизвести проблему с помощью AspectJ 1.8.8 и весной 4.2.5. Here - мой мультимодульный подход 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(); 
    } 
} 
+0

Спасибо за ваш тщательный ответ. Я все еще не мог найти разницы между моим кодом и вашим. Я предполагаю, что это связано с тем, что весна загружает класс '@ Configuration' (фактически более одного) автоматически и что-то там теряется. Я буду рыть. – Avi

+0

@Avi вы могли бы показать, как вы импортируете 'MetricsConfiguration' в ваше приложение? Это отличается от моего примера? – vsminkov

+0

Да, я обновил вопрос - добавил он в конце. – Avi