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

Java 如何在Hybris中覆盖GetOrderSubtotalAfter折扣以从小计中排除受限产品,java,aspectj,spring-aop,hybris,promotions,Java,Aspectj,Spring Aop,Hybris,Promotions,可能是一个重复的问题 我们正在使用升级模块(已弃用)。OOTB如果您有产品限制,并且您有混合购物车(允许和限制的产品),则促销(例如:订单阈值促销)将应用(计算)整个购物车总额理想情况下,限制性产品的价格应排除在购物车总价之外,以触发促销,这正是我想要实现的。 为此,我尝试使用SpringAOP覆盖getOrderSubtotalAfterDiscounters,并调用它。但是在那里,我需要获取当前的升级类实例(OrderPromotion)来调用PromotionsManager的Evalua

可能是一个重复的问题

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

为此,我尝试使用SpringAOP覆盖
getOrderSubtotalAfterDiscounters
,并调用它。但是在那里,我需要获取当前的升级类实例(OrderPromotion)来调用
PromotionsManager的
EvaluaterRestrictions
。但是使用
(OrderPromotion)pjp.getTarget()

方面:

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>


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

您不需要在此处使用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>


注意:您的
CustomOrderPromotion
应该继承自
OrderPromotion

您的特性不导入
de.hybris.platform.promotions.jalo.OrderPromotion
,并且不在同一个包中。所以我真的很想知道为什么它甚至应该编译为您试图使用的cast to
OrderPromotion

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

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


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

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

  • 将两个方法执行拉入两个单独的切入点
  • 然后使用
    args()
    target()
    将捕获的值直接绑定到切入点参数
  • 然后将切入点和建议方法中的所有参数结合起来:
@方面
公共类AbstractOrderAOP{
// (...)
@切入点(
“执行(公共**..OrderThreshold折扣百分比促销。评估(..)&&”+
“目标(订单促销)”
)
public void evaluatePointcut(OrderPromotion OrderPromotion){}
@切入点(
“执行(受保护**..OrderPromotion.GetOrderSubtotalAfter折扣(..)&&”+
参数(ctx,订单)
)
public void小计切入点(SessionContext ctx,AbstractOrder){}
@大约(“cflow(evaluatePointcut(orderPromotion))和小计Pointcut(ctx,order)”)
公共对象GetOrderSubtotal(
处理接合点pjp,
订单促销订单促销,
SessionContext ctx,
抽象订单
) {
LOG.info(“AbstractOrderAOP正在评估中”;
试一试{
最终对象输出=pjp.procedure();
}捕获(可丢弃的e){
e、 printStackTrace();
}
ArrayList产品=新的ArrayList();
// (...)
返回0升;
}
// (...)
}
看到了吗?不再有丑陋的
getTarget()
getArgs()[0]
,而是完美的类型安全参数绑定

顺便说一句,您不需要像我那样将包名缩写为
*..
。我只是想让你和这里的其他人更容易理解


这是可行的,我已经测试过了,通过复制你所有十几个被归类为傻瓜的东西(这里的代码太多了)。

只是在将它复制到你的so问题之前删除了它。
-是的,我这样做了。早些时候,没有对订单促销进行强制转换,我只是将其更改为打开,以演示我想做什么。是的,你们是对的,这个方法是静态的。我想这可能就是原因。我已经用OrderThreshold折扣百分比促销和OrderPromotion更新了问题。有没有其他方法可以在aspectYes中找到当前来电者(OrderThresholdDiscountPercentagePromotion的一个实例)是的,AspectJ可以很好地解决您的问题,但我不能在周六或周日之前帮您,因为我旅行时没有PC,我想提供代码,而不仅仅是文字。抱歉让您久等了。如承诺的那样,我将解决方案源代码作为更新添加到我的答案中。享受吧!为了学习AspectJ的基础知识,我建议阅读。特别是为了更好地理解
cflow()
cflowdown()
,请阅读。我认为这不起作用,因为我想在所有OOTB订单促销中实现这种行为,
1>
OrderPromotion是抽象类
2>
所有OOTB促销间接扩展OrderPromotion
3>
GetOrderSubtotalAfterPromotion是静态方法
4>
超出自定义类(
CustomOrderPromotion
)不会调用,因为它不会被引用。我们也不能为它声明bean,因为它也是抽象的。如果我错了,请纠正我。另外,该方法是
final
,因此无法重写。检查我更新的问题。啊,我知道你现在想要实现什么,不幸的是
getOrderSubtotal