Spring注解与我的设计准则相冲突
概述
使用
- Spring 3.0.1(注解配置)
- 当前配置使用 CGLib 作为代理创建者,但这不是我的偏好
- 交易是注释配置的,没有任何特殊设置
- 所有配置均通过注释完成(
@Service
、@Transactional
、@ManagedResource
、@Inject
、等)
- Hibernate 3.5(实体使用 javax.persistence 进行注释)
指南突出显示
- 每个使用
@Repository 或
@Service
必须有一个接口 - Constructor DI(当不需要重新配置时)
- 构造函数具有默认可见性 (
Foo(Bar bar) {...}
)
- 构造函数具有默认可见性 (
- Bean 字段是最终(重新配置时)不是必需的)
- 导致没有默认构造函数
- 函数默认实现通过final修饰符可见(
final class Foo
)
问题
- CGLib 无法代理最终类
- CGLib 需要默认(空)构造函数
- 某些服务需要通过 JMX
- MBean 导出器公开,除非由 CGLib 代理,否则无法工作
- 某些
@Transactional
@Service< /code> 通过外观服务进行访问,该服务需要在外观事务中包含多个服务(例如超过 2 个应用程序组件的观察者服务)
- 某些接口具有多个实现(当前通过 @Qualifier 来区分) >)
- 未来指南(或者最好有功能) - 每个应用程序模块将有
beanRefContext.xml
文件来配置其内部应用程序上下文
当我使用 XML 配置时,我能够强制执行所有指南我在上面介绍过,但是当切换到注释时,Spring 似乎行为不当。
我小组中的开发人员更喜欢注释配置(我似乎更容易连接和编写新代码),但我注意到他们在代码中引入了各种“黑客”,以防止处理 Spring 应用程序上下文故障。
问题
- 使用注释配置时是否应该遵循最佳实践?
- 每个接口使用多个实现时(尝试减少
@Primary
或@Qualifier
的使用) - 使用
@Transactional
时 - 使用
@ManagedResource
时 - 结合使用上述内容时
- 每个接口使用多个实现时(尝试减少
- 有没有办法停止使用 CGLib,保留注释配置并仍然能够使用注释导出我的 MBean?
- 保留大部分(最好是全部)指南的合适实施是什么?
Overview
Using
- Spring 3.0.1 (annotation configuration)
- Current configuration is using CGLib as proxy creator but this is not my preference
- Transactions are annotation configured without any special settings
- All configuration is done with annotations (
@Service
,@Transactional
,@ManagedResource
,@Inject
, etc.)
- Hibernate 3.5 (entities are annotated with javax.persistence)
Guidelines highlights
- Every bean annotated with
@Repository
or@Service
must have an interface - Constructor DI (when re-configuration isn't required)
- Constructor has default visibility (
Foo(Bar bar) {...}
)
- Constructor has default visibility (
- Bean fields are final (when re-configuration isn't required)
- Leads to no default constructor
- Implementations are default visible with final modifier (
final class Foo
)
The Problem
- CGLib can't proxy final classes
- CGLib requires default (empty) constructor
- Some services are required to be exposed via JMX
- MBean exporter can't work unless proxied by CGLib
- Some
@Transactional
@Service
s are accessed via facade service which requires more than one service to include in the facade transaction (e.g. Observer service over 2 application components) - Some interfaces have more than one implementation (which currently distinguished by
@Qualifier
) - Future guideline (or nice to have feature) - each application module will have
beanRefContext.xml
file to configure its internal application context
When I used to work with XML configuration I was able to enforce all the guidelines I presented above, but when switching to annotations it seems like Spring is misbehaving.
Developers in my group prefer annotation configuration (I seems easier to wire and write new code), but I've noticed all kind of "hacks" they introduce to the code to prevent from dealing with Spring application context failures.
The Question(s)
- Are there best practices I should follow when using annotation configuration?
- When using more than one implementation per interface (trying to reduce the use of
@Primary
or@Qualifier
) - When using
@Transactional
- When using
@ManagedResource
- When using a combination of the above
- When using more than one implementation per interface (trying to reduce the use of
- Is there a way of stop working with CGLib, keep the annotation configuration and still be able to export my MBeans with annotations?
- What is the suitable implementation for keeping most (preferably, all) of my guidelines?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我提出了以下解决方案(针对问题 #2 和 #3),以便能够执行我的设计准则并继续使用基于注释的配置:
ApplicationContext
beanRefContext.xml
中定义。上述步骤还使我能够减少 Spring 感知测试的执行时间(每个模块仅加载 bean 的子集)。
作为实用指南(针对问题#1),如果一个接口有多个实现,我将
@Primary
放置在广泛使用的一个和其他客户端上,需要另一种实现,使用连接 bean >@限定符
。I came up with the following solution (to questions #2 and #3) to be able to enforce my design guidelines and keep using annotation based configuration:
ApplicationContext
beanRefContext.xml
The above steps also enabled me to reduce the execution time of Spring aware tests (every module loaded only a sub-set of beans).
As a practical guideline (for question #1), if an interface has more than one implementation, I place
@Primary
on the widely used one and other clients, requiring another implementation, wire the bean using@Qualifier
.回答第2点)
您可以使用 AspectJ 而不是 CGLib。
Answer to point 2)
You could use AspectJ instead of CGLib.