【问题标题】:Spring dependency injection or aspect programmingSpring依赖注入或方面编程
【发布时间】:2009-01-17 02:16:21
【问题描述】:

我需要几个类中的方法,这些方法必须始终遵循特定的前后模式。

公共无效方法(X x, Y y) {

// ************重复部分开始******************/

AFrameworkClass aFrameworkClass = new AFrameworkClass (this.memberVariable,"SomeString");

试试{

  aFrameworkClass.aFrameworkMethod( x,y); 
  aFrameworkClass.anotherFrameworkMethod(x,y); 
  aFrameworkClass.yetAnotherFrameworkMethod(x);   
  aFrameworkClass.doPreProcessing(); 

  Throwable t = null ; 

// ************重复部分结束 ******************/

  try { 
     // code will vary according to the business logic 
  } 
  catch (Throwable t) { 
     // code will vary according to the business logic   
  } 

// ************重复部分开始******************/

  aFrameworkClass.doPostProcessing(); 

} 最后 { aFrameworkClass.doCleanup();

}

// ************重复部分结束 ******************/

}

是否可以使用 Spring 框架来完成该方法中重复部分的逻辑,而不必在我的各个类中一遍又一遍地编写这些代码行?如果有怎么办?

【问题讨论】:

    标签: spring aop


    【解决方案1】:

    绝对可以通过 Spring 的 AOP 支持来完成。您可以将第一部分应用为“之前”建议,将第二部分应用为“最后”建议,或者您可以将两者都应用为“围绕”建议并以编程方式调用目标方法,如下所示:

    methodInvocation.invoke(); // returns Object
    

    如果你想在 XML 中声明你的切面,你可以在这里阅读如何做:

    http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema-advice-before http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-schema-advice-after-finally http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-ataspectj-around-advice

    或者如果你想用注释来做,这里有信息:

    http://static.springframework.org/spring/docs/2.5.x/reference/aop.html#aop-ataspectj

    我个人更喜欢使用 XML,因为无需重新编译应用程序就可以更改方面的行为。假设您有一个多模块项目,其中 B 依赖于 A。A 包含可重用的建议,并且正在使用注释来处理订单、切入点等。如果您需要更改该行为,则必须重新构建 A。如果您在项目 B 中使用 XML从项目 A 配置切面,不需要重建 A。

    我的感觉是,当您在类中定义行为以及如何在 XML 中应用该行为时,建议更可重用。

    【讨论】:

    • “我个人更喜欢用 XML 来做这件事,因为可以在不重新编译应用程序的情况下更改方面的行为”,您指的是什么确切
    • AspectJ API 中有一些注释允许您在 Java 代码中定义 AOP 行为:static.springframework.org/spring/docs/2.5.x/reference/… 例如,您可以使用 @Order 指定通知顺序。我宁愿使用 XML 代替;易于更改,无需编译
    • XML 配置文件通常打包在 EAR 或 WAR 中。您必须重新构建项目才能重新打包,这反过来又引入了回归测试的需求
    • 更好的理由:当您在类中定义行为以及如何在 XML 中应用它时,它使建议更可重用。特别是对于切入点或顺序之类的东西,您将希望逐个项目地更改该项目,而不是将其“烘焙”到您的代码中。
    • 另外:假设您有一个多模块项目,其中 B 依赖于 A。A 包含可重用的建议,并使用注释来处理订单、切入点等。如果您需要更改该行为,则必须重新构建A. 如果您在项目 B 中使用 XML 来配置项目 A 的切面,则无需重新构建 A。
    【解决方案2】:

    作为成熟的 IoC 容器的替代方案,您可以使用委托来实现相同的目的。设计一个具有前置和后置功能的基类以及一个委托来注入您不同的业务逻辑功能。 “RunProcess”基类函数将调用前操作、委托,然后是后操作。

    【讨论】:

    • 啊,这种模式似乎比使用 IoC 框架更容易理解。我会试试这个。
    【解决方案3】:

    brd6644 是对的,但我发现 Spring AOP 的一个问题是建议/顾问在您创建对象时无法应用于属性。

    也就是说,假设你有类似的东西

    <bean class="...ProxyBeanFactory">
        <property name="target">
            <bean class="myBean">
                <property name="username" value="helloKitty"/>
                <property name="password" value="lkajdahdkahjdkhja"/>
            </bean>
         </property>
     </bean>
    

    不可能编写顾问程序来解密 myBean 的密码,因为在创建代理之前提供了属性值。当然,您不能将密码属性应用于 ProxyBeanFactory 类。您真正想要做的是使用“lkaj...”参数对从 ProxyBeanFactory 返回的对象调用 setPassword(),但这似乎是不可能的。

    【讨论】:

    • 您制作了一个“加密”PropertyPlaceholderConfigurer 来执行此操作。我相信这实际上是 PropertyPlaceholderConfigurer 下 spring 参考中的一个示例
    猜你喜欢
    • 2010-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-11-21
    • 2012-12-23
    • 1970-01-01
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多