AOP Spring Before 建议不起作用

发布于 2024-11-05 02:46:38 字数 899 浏览 2 评论 0原文

方法 DefaultProduitGeneriqueService.valider 没有被方法traceWhenReturnedValueDoesntExistOrNotNecessary捕获,我不明白为什么?

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) {
       ...
    }

}

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,traceable")
    public void traceWhenReturnedValueDoesntExistOrNotNecessary(ElementNiveauUn element, Traceable traceable) {
       ...
    }

}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

尘世孤行 2024-11-12 02:46:39

假设服务接口位于包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基于接口的代理,所以你的切入点表达式应该匹配接口方法执行,而不是实现方法执行,并且您的切入点表达式可能匹配接口方法执行或实现方法执行。

请记住使用例如 标记在配置中包含 AspectJAutoProxyCreator

这里有一个简单的测试来证明一切正常:

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.. *.*(..)

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..*.*(..)
掩饰不了的爱 2024-11-12 02:46:39

确保两个 bean 都通过注释或在 appCtx 中正确配置。

看起来你的方面肯定是对的,但是其他职业呢? Spring 是否已启用?

另外,如果这两个类确实配置正确,您确定传递的实例是 Spring bean 而不是构造函数中的“新”实例吗?

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?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文