概观
运用
> Spring 3.0.1(注释配置)
>当前配置使用CGLib作为代理创建者,但这不是我的偏好
>事务是没有任何特殊设置的配置注释
>所有配置都使用注释完成(@ Service,@ Transaction,@ ManagedResource,@ Inject等)
> Hibernate 3.5(实体用javax.persistence注释)
指南重点
>每个使用@Repository或@Service注释的bean都必须具有接口
>构造函数DI(不需要重新配置时)
>构造函数具有默认可见性(Foo(条形栏){…})
> Bean字段是最终的(不需要重新配置时)
>导致没有默认构造函数
>使用final修饰符(最终类Foo)默认可见实现
问题
> CGLib无法代理最终类
> CGLib需要默认(空)构造函数
>某些服务需要通过JMX公开
>除非CGLib代理,否则MBean导出器无法工作
>通过Facade服务访问一些@Transactional @Services,这需要在facade事务中包含多个服务(例如,2个应用程序组件上的Observer服务)
>某些接口有多个实现(目前由@Qualifier区分)
>未来指南(或很高兴有功能) – 每个应用程序模块都有beanRefContext.xml文件来配置其内部应用程序上下文
当我以前使用XML配置时,我能够执行上面提到的所有指导,但是当切换到注释时,Spring似乎行为不端.
我的小组中的开发人员更喜欢注释配置(我似乎更容易编写和编写新代码),但我注意到他们为代码引入了所有类型的“黑客”,以防止处理Spring应用程序上下文失败.
问题
>使用注释配置时是否应该遵循最佳实践?
>每个接口使用多个实现时(尝试减少@Primary或@Qualifier的使用)
>使用@Transactional时
>使用@ManagedResource时
>使用上述组合时
>有没有办法停止使用CGLib,保留注释配置并仍然可以导出带有注释的MBean?
>保留大部分(最好是全部)指南的合适实施方案是什么?
解决方法:
我提出了以下解决方案(问题#2和#3),以便能够执行我的设计指南并继续使用基于注释的配置:
>每个依赖项目(Maven模块)都有自己的ApplicationContext
>每个依赖项目应用程序上下文都在beanRefContext.xml中定义
>使用Spring上下文层次结构机制将这些应用程序上下文加载到层次结构中.
> Spring实际上并不完全支持此步骤,需要额外的work
>由于我的应用程序是分层的,我可以在除JMX层之外的所有模块上禁用CGLib(我可以忍受它:-)).
上述步骤还使我能够减少Spring感知测试的执行时间(每个模块只加载一个bean的子集).
作为一个实用指南(对于问题#1),如果一个接口有多个实现,我将@Primary放在广泛使用的一个和其他客户端上,需要另一个实现,使用@Qualifier连接bean.