开发者

AOP Spring Before Advice not working

开发者 https://www.devze.com 2023-03-02 16:40 出处:网络
The method DefaultProduitGeneriqueService.valider is not catched by the method traceWhenReturnedValueDoesntExistOrNotNecessary and I don\'t understand why?

The method DefaultProduitGeneriqueService.valider is not catched by the method traceWhenReturnedValueDoesntExistOrNotNecessary and I don't understand why?

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,t开发者_运维问答raceable")
    public void traceWhenReturnedValueDoesntExistOrNotNecessary(ElementNiveauUn element, Traceable traceable) {
       ...
    }

}


Assuming that the service interfaces are in package fr.generali.nova.atp.service.metier.api:

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

public interface IProduitGeneriqueService {

    void valider(ElementNiveauUn element);
}

And the service implementations are in package 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
    }
}

Your aspect should look like this:

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...");
    }
}

The default proxy strategy for Spring AOP is JDK interface-based proxies, so Your pointcut expression should match the interface method execution, not the implementation method execution, and Your poincut expression may match either interface mothod execution or implementation method execution.

And remember to include an AspectJAutoProxyCreator in your configuration using for example <aspectj-autoproxy /> tag.

And here is a simple test to prove everyting is working:

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");
    }
}

The err output is:

BEFORE
traced...
AFTER

For all combinations:

  • fr.generali.nova.atp.service.metier.api.*.*(..)
  • fr.generali.nova.atp.service.metier.impl.*.*(..)
  • fr.generali.nova.atp.service.metier..*.*(..)


Make sure both beans are properly configured, either through annotations or in your appCtx.

It looks like your Aspect is definitely right, but how about the other class? Is it Spring enabled?

Also, if both classes are indeed configured correctly, are you sure that the instance being passed is a Spring bean and not a "new" instance from a constructor?

0

精彩评论

暂无评论...
验证码 换一张
取 消