АОП Весна до консультации не работает - PullRequest
0 голосов
/ 04 мая 2011

Метод DefaultProduitGeneriqueService.valider не отлавливается методом traceWhenReturnedValueDoesntExistOrNotNeeded, и я не понимаю, почему?

package fr.generali.nova.atp.service.metier.impl;

public class DefaultProduitGeneriqueService extends DefaultService implements IProduitGeneriqueService, IBacAware {

...

@Override
@Traceable(value = ETraceableMessages.VALIDATION_PRODUIT_GENERIQUE, hasReturnedValue=Traceable.HAS_NOT_RETURNS_VALUE)
public void valider(ElementNiveauUn element) {
   ...
}
...
}

package fr.generali.nova.atp.logging.advisor;


@Aspect
public class TraceableAdvisor {

    @Before(value = "execution(* fr.generali.nova.atp.service.metier.impl.*.*(..)) && @annotation(traceable) && args(element)", argNames = "element,traceable")
    public void traceWhenReturnedValueDoesntExistOrNotNecessary(ElementNiveauUn element, Traceable traceable) {
       ...
    }

}

Ответы [ 2 ]

0 голосов
/ 05 мая 2011

Предполагая, что сервисные интерфейсы находятся в пакете fr.generali.nova.atp.service.metier.api:

package fr.generali.nova.atp.service.metier.api;

public interface IProduitGeneriqueService {

    void valider(ElementNiveauUn element);
}

И реализации сервиса находятся в пакете fr.generali.nova.atp.service.metier.impl:

package fr.generali.nova.atp.service.metier.impl;

public class DefaultProduitGeneriqueServiceImpl implements IProduitGeneriqueService {

    @Override
    @Traceable(value = ETraceableMessages.VALIDATION_PRODUIT_GENERIQUE, hasReturnedValue=Traceable.HAS_NOT_RETURNS_VALUE)
    public void valider(ElementNiveauUn element) {
        // TODO: implement
    }
}

Ваш аспект должен выглядеть следующим образом:

package fr.generali.nova.atp.logging.advisor;

@Aspect
public class TraceableAdvisor {

    @Before(value = "execution(* fr.generali.nova.atp.service.metier.api.*.*(..)) && @annotation(traceable) && args(element)", argNames = "element,traceable")
    public void traceWhenReturnedValueDoesntExistOrNotNecessary(ElementNiveauUn element, Traceable traceable) {
         // TODO: implement
        System.err.println("traced...");
    }
}

Стратегия прокси по умолчанию для Spring AOP - это прокси на основе интерфейса JDK , поэтому ваше выражение pointcut должно совпадать с выполнением метода интерфейса *1018*, а не с реализацией метода реализации и вашим выражением poincut может соответствовать как выполнению интерфейса, так и выполнению метода.

И не забудьте включить AspectJAutoProxyCreator в вашу конфигурацию, используя, например, тег <aspectj-autoproxy />.

А вот простой тест, чтобы доказать, что все работает:

public class TraceableAdvisorTest {

    @Configuration
    public static class TestConfiguration {

        @Bean
        public IProduitGeneriqueService produitGeneriqueService() {
            return new DefaultProduitGeneriqueServiceImpl();
        }

        @Bean
        public TraceableAdvisor traceableAdvisor() {
            return new TraceableAdvisor();
        }

        @Bean
        public AnnotationAwareAspectJAutoProxyCreator autoProxyCreator() {
            return new AnnotationAwareAspectJAutoProxyCreator();
        }
    }

    private AnnotationConfigApplicationContext testApplicationContext;

    @Test
    public void testTraceWhenReturnedValueDoesntExistOrNotNecessary() {
        this.testApplicationContext = new AnnotationConfigApplicationContext();
        this.testApplicationContext.register(TestConfiguration.class);
        this.testApplicationContext.refresh();

        IProduitGeneriqueService service = BeanFactoryUtils.beanOfType(this.testApplicationContext, IProduitGeneriqueService.class);

        System.err.println("BEFORE");
        service.valider(null);
        System.err.println("AFTER");
    }
}

Выход err:

BEFORE
traced...
AFTER

Для всех комбинаций:

  • fr.generali.nova.atp.service.metier.api.*.*(..)
  • fr.generali.nova.atp.service.metier.impl.*.*(..)
  • fr.generali.nova.atp.service.metier..*.*(..)
0 голосов
/ 05 мая 2011

Убедитесь, что оба bean-компонента правильно настроены, либо с помощью аннотаций, либо в вашем appCtx.

Похоже, ваш аспект определенно прав, но как насчет другого класса?Включен ли Spring?

Кроме того, если оба класса действительно настроены правильно, вы уверены, что передаваемый экземпляр является компонентом Spring, а не "новым" экземпляром из конструктора?

...