【问题标题】:Spring AOP: Adding advice in a running applicationSpring AOP:在正在运行的应用程序中添加建议
【发布时间】:2011-06-04 07:12:07
【问题描述】:

如何在不重新启动服务器的情况下在正在运行的应用程序中添加或删除 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,promoCode,mappedURL" />
    </aop:aspect>
</aop:config>

这是促销活动之一...像上面一样,我还有其他 3 个,并且希望能够通过 aop 动态配置这些,而无需更改 xml 并重新启动服务器。请帮忙

【问题讨论】:

    标签: spring spring-aop


    【解决方案1】:

    我认为你不能,主要是因为 Spring 在上下文启动期间连接 bean。这意味着如果将 bean A 注入到 bean B 中,并且前者不是任何代理的包装器,它将直接注入。

    现在您当然可以使用A,将其包装在代理中并将其放回容器中(作为A' 的副本)。但是B 根本不知道A'

    如果您事先知道哪些 bean 受动态添加/删除方面的影响,请急切地将它们包装在启动时不执行任何操作的方面(例如调用NoOpStrategy)。当您需要“添加”方面时,只需将该策略更改为其他内容即可。

    【讨论】:

    • 感谢 Tomasz 的回复,但只是重申您的意思.. 例如,如果我假设有 4 种促销方面作用于同一个切入点(这是一个前端控制器)并且想要应用或删除它们动态的。我需要做什么?抱歉无知...不了解“NoOpStrategy”
    • @Abhi:我认为他的意思是你必须有静态切入点并且在 bean 创建期间在每个切入点应用至少一个方面(可能是微不足道的)。这是为了强制 Spring 在您的代码和 bean 的“外壳”之间插入方面处理机制,这样当您添加更多方面时,所有内容都已经设置好,可以插入这些方面。
    • +1 顺便说一句,这是一个优雅的解决方案,至少有很好的工作机会。
    猜你喜欢
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多