Spring AOP: Adding advice in a running application

廉价感情. 提交于 2019-12-25 01:07:02

问题


How can I add or remove Spring AOP proxies in a running application without restarting the server?

Something like this

    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());

My XML config looks like this:

<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,promoCode,mappedURL" />
    </aop:aspect>
</aop:config>

This is one of the promotions... Like the above i have 3 other and want to be able to configure these dynamically through aop without changing the xml and restarting the server. Please help


回答1:


I don't think you can, mainly because Spring wires beans during context startup. This means if bean A is injected into bean B and the former one is not wrapper with any proxy, it will be injected directly.

Now of course you can take A, wrap it in a proxy and put it back in the container (as a copy A'). But B does not know about A' at all.

If your know in advance which beans are subject to dynamic adding/removing aspects, wrap them eagerly in aspect that does nothing on startup (e.g. calling sort of NoOpStrategy). When you need to "add" the aspect, just change that strategy to something else.



来源:https://stackoverflow.com/questions/6235359/spring-aop-adding-advice-in-a-running-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!