Spring注释与我的设计指南相冲突

时间:2010-11-30 18:35:17

标签: java spring annotations cglib

概述
使用

  • Spring 3.0.1(注释配置)
    • 当前配置使用CGLib作为代理创建者,但这不是我的偏好
    • 事务是在没有任何特殊设置的情况下配置的注释
    • 所有配置均使用注释(@Service@Transactional@ManagedResource@Inject等完成。)
  • Hibernate 3.5(实体用javax.persistence注释)

指南重点

  • 每个使用@Repository@Service注释的bean都必须具有接口
  • 构造函数DI(不需要重新配置时)
    • 构造函数具有默认可见性(Foo(Bar bar) {...}
  • Bean字段 final (不需要重新配置时)
    • 导致没有默认构造函数
  • 使用最终修饰符(final class Foo
  • 实现默认

问题

  1. CGLib无法代理最终类
  2. CGLib需要默认(空)构造函数
  3. 某些服务需要通过JMX公开
  4. MBean导出器无法工作,除非由CGLib代理
  5. 通过外观服务访问某些@Transactional @Service,这需要在外观事务中包含多个服务(例如,2个应用程序组件上的Observer服务)
  6. 某些接口有多个实现(目前由@Qualifier区分)
  7. 未来指南(或很高兴有功能) - 每个应用程序模块都有beanRefContext.xml文件来配置其内部应用程序上下文
  8. 当我以前使用XML配置时,我能够执行上面提到的所有指导,但是当切换到注释时,看起来Spring似乎行为不端。
    我的小组中的开发人员更喜欢注释配置(我似乎更容易编写和编写新代码),但我注意到他们为代码引入了所有类型的“黑客”,以防止处理Spring应用程序上下文失败。

    问题

    1. 使用注释配置时是否应该遵循最佳做法?
      • 每个界面使用多个实现时(尝试减少@Primary@Qualifier的使用)
      • 使用@Transactional
      • 使用@ManagedResource
      • 使用上述
      • 的组合时
    2. 有没有办法停止使用CGLib,保留注释配置并仍然可以使用注释导出我的MBean?
    3. 保留大部分(最好是全部)指南的合适方法是什么?

2 个答案:

答案 0 :(得分:3)

我想出了以下解决方案(问题#2和#3),以便能够执行我的设计指南并继续使用基于注释的配置:

  • 每个依赖项目(Maven模块)都有自己的ApplicationContext
  • 每个依赖项目应用程序上下文都在beanRefContext.xml
  • 中定义
  • 使用Spring上下文层次结构机制将这些应用程序上下文加载到层次结构中。
    • Spring实际上并不完全支持此步骤,需要额外的work
  • 由于我的应用程序是分层的,我可以在除JMX层之外的所有模块上禁用CGLib(我可以忍受它:-))。

上述步骤还使我能够减少Spring感知测试的执行时间(每个模块只加载一个bean的子集)。

作为一个实用指南(对于问题#1),如果一个接口有多个实现,我将@Primary放在广泛使用的一个和其他客户端上,需要另一个实现,使用{{1}连接bean }}

答案 1 :(得分:1)

回答第2点) 您可以使用AspectJ而不是CGLib。