当前位置: 首页 > 知识库问答 >
问题:

如何在Hybris中覆盖GetOrderSubtotalAfter折扣以从小计中排除受限产品

拓拔弘化
2023-03-14

可能是专家的重复问题。海布里斯

我们正在使用升级模块(已弃用)。OOTB如果你有产品限制,并且你有混合购物车(允许和限制的产品),那么促销(比如:订单阈值促销)将应用(计算)整个购物车总数。理想情况下,限制性产品的价格应该从购物车总额中排除,以触发促销,这就是我想要实现的目标。

要做到这一点,我试图使用Spring AOP覆盖getOrderSub汇总后折扣,并且它也被调用。但是在那里,我需要获得当前的促销类实例(Order促销)来调用促销管理器评估限制。但是它总是使用(订单促销)pjp.get目标()为空

方面:

package com.myproject.aop;

@Aspect
public class AbstractOrderAOP
{

    private static final Logger LOG = Logger.getLogger(AbstractOrderAOP.class);


    @Pointcut("execution(public * *..OrderThresholdDiscountPercentagePromotion.evaluate(..)) && target(orderPromotion)")
    public void evaluatePointcut(OrderPromotion orderPromotion)
    {
        //
    }

    @Pointcut("execution(protected * de.hybris.platform.promotions.jalo.OrderPromotion.getOrderSubtotalAfterDiscounts(..)) && args(ctx, order)")
    public void subtotalPointcut(SessionContext ctx, AbstractOrder order)
    {
        //
    }

    @SuppressWarnings("boxing")
    @Around("evaluatePointcut(orderPromotion) && cflow(subtotalPointcut(ctx, order))")
    public Object getOrderSubtotalAfterDiscounts(ProceedingJoinPoint pjp, OrderPromotion orderPromotion, SessionContext ctx,
            AbstractOrder order)
    {
        LOG.info("here you go ....");
        return 0l;
    }
}

aop.xml

<aspectj>
    <weaver options="-Xset:weaveJavaxPackages=true">
        <include within="de.hybris.platform.promotions.jalo.OrderPromotion"/>
        <include within="de.hybris.platform.b2bacceleratorservices.jalo.promotions.OrderThresholdDiscountPercentagePromotion"/>
        <include within="com.myproject.extended.interceptor.*"/>
    </weaver>
    <aspects>
        <aspect name="com.myproject.aop.AbstractOrderAOP"/>
    </aspects>
</aspectj>

任何帮助或建议都将不胜感激!!

共有2个答案

柳钟展
2023-03-14

您不需要在这里使用AOP,只需覆盖OrderPromotion,您就可以:

<bean id="de.hybris.platform.promotions.jalo.OrderPromotion" 
    class="foo.bar.CustomOrderPromotion" 
    scope="prototype">

    <property name="timeService" ref="timeService" />
    <property name="cartService" ref="cartService" />

</bean>

注意:您的CustomOrder推销应该继承自Order推销

明财
2023-03-14

你的方面没有导入de.hybris.platform.promotions.jalo.Order推销,并且不在同一个包中。所以我真的很想知道为什么它甚至应该与你试图使用的Order推销的演员一起编译。

如果您的方面中确实有导入,并且只是在将其复制到SO问题之前擦除了它,我看不出为什么pjp.getTarget()会产生null,只有一个例外:如果方法是静态的,那么它当然不会有一个目标对象被调用,因为没有对象实例。在这种情况下,您的方面无法工作,您需要拦截另一个切入点。

由于Hybris在网络上似乎没有任何公共JavaDoc,而且我从未使用过它,因此无法访问它,因此我不能确定,我不得不猜测。

更新:好的,我旅行回来了,有点时间回答。基本上,我们的想法是

  • 调用实例方法和
  • 来自静态方法的参数

为了实现这一点,您可以使用cflow()切入点,通过该切入点可以表示,如果静态方法的执行位于获取目标对象的实例方法的控制流中(即直接或间接调用),则应捕获静态方法的执行。你应该

  • 将两个方法执行分成两个单独的切入点,
  • 然后使用args()目标()将捕获的值直接绑定到切点参数
  • 然后将切入点和建议方法中的所有参数组合起来:
java prettyprint-override">@Aspect
public class AbstractOrderAOP {

  // (...)

  @Pointcut(
    "execution(public * *..OrderThresholdDiscountPercentagePromotion.evaluate(..)) && " +
    "target(orderPromotion)"
  )
  public void evaluatePointcut(OrderPromotion orderPromotion) {}

  @Pointcut(
    "execution(protected * *..OrderPromotion.getOrderSubtotalAfterDiscounts(..)) && " +
    "args(ctx, order)"
  )
  public void subtotalPointcut(SessionContext ctx, AbstractOrder order) {}

  @Around("cflow(evaluatePointcut(orderPromotion)) && subtotalPointcut(ctx, order)")
  public Object getOrderSubtotalAfterDiscounts(
    ProceedingJoinPoint pjp,
    OrderPromotion orderPromotion,
    SessionContext ctx,
    AbstractOrder order
  ) {

    LOG.info("############ AbstractOrderAOP is being evaluated ############");
    try {
      final Object output = pjp.proceed();
    } catch (Throwable e) {
      e.printStackTrace();
    }

    ArrayList products = new ArrayList();

    // (...)

    return 0l;
  }

  // (...)
}

看到了吗?不再有丑陋的getTarget()getArgs()[0],而是完全类型安全的参数绑定。

顺便说一句,您不需要将包名缩写为*

这是可行的,我已经通过复制所有十几个被归类为假人的代码(太多代码无法在这里发布)测试了它的效果。

 类似资料:
  • 我想以某种方式使用Jacoco,这样它就排除了。为了实现这一点,我加入了

  • 如何排除来自jacoco code coverage,在pom中。xml还是java代码?

  • 我的项目中有一个com.org.projectname.model包。我想做的是,从SonarQube覆盖范围中排除此包中的所有文件。我试过了,和,仍然没有成功。 如何解决这个问题?或者还有别的办法吗?

  • 我试图弄清楚如何从由Jenkins启动的Jacoco生成的代码覆盖率报告中排除文件夹列表。 似乎可以排除类,但不能排除文件夹,这让我很恼火,因为我已经开始使用一个相当大的在线支付系统库。运行那些单元测试意味着不断地在那个平台上创建测试帐户,并且不得不再次删除它们。詹金斯跑步的每一分钟。 并且仅仅排除文件夹比必须排除每一个类要简单得多。

  • 当我的Jenkins管道失败时,试图从覆盖报告中排除包。我有一个包含所有POJO: s的子项目。我不想为所有这些编写uittest。因此,它们会拖累覆盖范围将低于阈值的分支/线路覆盖范围,并使我的构建失败。 应该可以排除一些包,但我无法让它工作。 我有以下雅各布.gradle文件: 以下是我的声纳.gradle文件中的内容: 在我的build.gradle中: 最后从我的詹金斯文件中: 但是,xx

  • 问题内容: 有没有一种方法可以将代码排除在Cobertura覆盖率报告之外?我们提供了一些不应包含在覆盖率报告中的方法,因此不会降低覆盖率。 我知道四叶草具有这样的功能,但是我还没有为Cobertura找到任何类似的东西。 问题答案: 您可以从检测中排除类。然后它们不应出现在报告中。请参阅下面的 排除 语句。 您也可以忽略对某些方法的调用。请参阅下面的 ignore 语句。 如果您使用的是mave