Java 如何在Hybris中覆盖GetOrderSubtotalAfter折扣以从小计中排除受限产品
可能是一个重复的问题 我们正在使用升级模块(已弃用)。OOTB如果您有产品限制,并且您有混合购物车(允许和限制的产品),则促销(例如:订单阈值促销)将应用(计算)整个购物车总额理想情况下,限制性产品的价格应排除在购物车总价之外,以触发促销,这正是我想要实现的。 为此,我尝试使用SpringAOP覆盖Java 如何在Hybris中覆盖GetOrderSubtotalAfter折扣以从小计中排除受限产品,java,aspectj,spring-aop,hybris,promotions,Java,Aspectj,Spring Aop,Hybris,Promotions,可能是一个重复的问题 我们正在使用升级模块(已弃用)。OOTB如果您有产品限制,并且您有混合购物车(允许和限制的产品),则促销(例如:订单阈值促销)将应用(计算)整个购物车总额理想情况下,限制性产品的价格应排除在购物车总价之外,以触发促销,这正是我想要实现的。 为此,我尝试使用SpringAOP覆盖getOrderSubtotalAfterDiscounters,并调用它。但是在那里,我需要获取当前的升级类实例(OrderPromotion)来调用PromotionsManager的Evalua
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 toOrderPromotion
如果您的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促销间接扩展OrderPromotion3>
GetOrderSubtotalAfterPromotion是静态方法4>
超出自定义类(CustomOrderPromotion
)不会调用,因为它不会被引用。我们也不能为它声明bean,因为它也是抽象的。如果我错了,请纠正我。另外,该方法是final
,因此无法重写。检查我更新的问题。啊,我知道你现在想要实现什么,不幸的是getOrderSubtotal