可能是 experts.hybris 的重复问题
我们正在使用促销模块(已弃用)。 OOTB 如果您有产品限制并且您有混合购物车(具有允许和限制的产品),则促销(例如:订单阈值促销)将适用(计算)整个购物车总数。 理想情况下,受限制的产品价格应从购物车总额中排除以触发促销,这就是我想要实现的目标。
为此,我尝试使用 Spring AOP 覆盖 getOrderSubtotalAfterDiscounts
并且它也被调用。但在那里,我需要获取当前促销类实例 (OrderPromotion) 来调用 PromotionsManager
的 evaluateRestrictions
。但使用 (OrderPromotion) pjp.getTarget() 总是得到 null
方面:
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>
如有任何帮助或建议,我们将不胜感激!!
最佳答案
您的方面不导入 de.hybris.platform.promotions.jalo.OrderPromotion
并且不在同一个包中。所以我真的想知道为什么它甚至应该通过强制转换来编译 OrderPromotion
您正在尝试使用。
如果您的方面确实有导入,并且在将其复制到您的SO问题之前只是将其删除,我认为没有理由 pjp.getTarget()
应该产生 null
,但有一个异常(exception):如果方法是静态的,那么它当然不会有要调用的目标对象,因为没有对象实例。在这种情况下,您的方面无法工作,您需要拦截另一个切入点。
由于 Hybris 似乎在网络上没有任何公共(public) JavaDoc,而且我从未使用过它,因此无法访问它,所以我不能肯定地说,我必须推测。
更新:好的,我旅行回来了,有一点时间来回答。基本上这个想法是得到
- 调用实例方法的目标和
- 来自静态方法的参数。
为了实现这一点,您可以使用 cflow()
切入点,您可以通过它表示如果静态方法位于控制流中(即直接或间接调用)获取目标对象的实例方法,则应该捕获该静态方法的执行。你应该
- 将两个方法执行拉出到两个单独的切入点中,
- 然后使用
args()
和target()
为了将捕获的值直接绑定(bind)到切入点参数 - 然后将切入点和所有参数组合到您的建议方法中:
@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]
,但完全类型安全的参数绑定(bind)。
顺便说一句,您不需要将包名称缩写为 *..
就像我一样。我只是想让它对您和这里的其他人来说更具可读性。
这是有效的,我已经通过复制所有被归类为傻瓜的十几个左右来测试它的效果(这里发布的代码太多)。
关于java - 如何重写 getOrderSubtotalAfterDiscounts 以从 Hybris 的小计中排除受限产品,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49726241/