问题描述
|
如何在不重新启动服务器的情况下在运行的应用程序中添加或删除Spring AOP代理?
像这样
GenericApplicationContext ctx = new GenericApplicationContext();
BeanDeFinitionBuilder promotion4Advice = BeanDeFinitionBuilder.rootBeanDeFinition(Promotion4Action.class).addPropertyValue(\"discountPercentage\",0.5);
promotion4Advice.addPropertyValue(\"discountCode\",16);
promotion4Advice.addPropertyValue(\"discountComment\",\"50% on regular item\");
ctx.registerBeanDeFinition(\"promotion4Advice\",promotion4Advice.getBeanDeFinition());
BeanDeFinitionBuilder builder = BeanDeFinitionBuilder.rootBeanDeFinition(Proxyfactorybean.class);
builder.addPropertyValue(\"proxyTargetClass\",true);
builder.addPropertyValue(\"interceptorNames\",new String[] {\"promotion4Advice\"});
ctx.registerBeanDeFinition(\"proxyfactorybean\",builder.getBeanDeFinition());
我的XML配置如下所示:
<bean id=\"promotion4Advice\"
class=\"com.promotion.actions.Promotion4Action\">
<property name=\"discountPercentage\" value=\"0.5\" />
<property name=\"discountCode\" value=\"16\" />
<property name=\"discountComment\" value=\"50% on regular item\" />
</bean>
<aop:config proxy-target-class=\"true\">
<aop:aspect id=\"promotion4Aspect\" ref=\"promotion4Advice\">
<aop:pointcut id=\"promotion4pointcut\"
expression=\"execution(* com.controller.ShoppingBagController.defaultHandler(javax.servlet.http.HttpServletRequest)) and args(request)\" />
<aop:before pointcut-ref=\"promotion4pointcut\" method=\"applyPromotion4\"
arg-names=\"request\" />
</aop:aspect>
<aop:aspect id=\"promotion4Aspect1\" ref=\"promotion4Advice\">
<aop:pointcut id=\"promotion4pointcut1\"
expression=\"execution(* com.controller.ReviewOrderController.handleRequest(javax.servlet.http.HttpServletRequest)) and args(request)\" />
<aop:before pointcut-ref=\"promotion4pointcut1\" method=\"interceptOrderDetails\"
arg-names=\"request\" />
</aop:aspect>
<aop:aspect id=\"promotion4Aspect4\" ref=\"promotion4Advice\">
<aop:pointcut id=\"promotion4pointcut4\"
expression=\"execution(* com.controller.ShoppingBagController.applyPromoCode(javax.servlet.http.HttpServletRequest,String,String)) and args(request,promoCode,mappedURL)\" />
<aop:after pointcut-ref=\"promotion4pointcut4\" method=\"interceptPromoCode\"
arg-names=\"request,mappedURL\" />
</aop:aspect>
</aop:config>
这是促销活动之一...像上面一样,我还有3个,并且希望能够通过aop动态配置这些,而无需更改xml和重新启动服务器。请帮忙
解决方法
我不认为可以,主要是因为Spring在上下文启动期间连接了bean。这意味着如果将豆
A
注入到豆B
中,并且前一个没有任何代理的包装,它将直接注入。
现在,您当然可以拿A
,将其包装在代理中,然后放回容器中(作为副本A\'
)。但是B
根本不了解A\'
。
如果您事先知道哪些bean受到动态添加/删除方面的约束,请将它们急切地包装在启动时不起作用的方面(例如,调用NoOpStrategy
之类)。当您需要“添加”方面时,只需将该策略更改为其他内容即可。