Spring注解与我的设计准则相冲突

发布于 2024-10-05 14:48:02 字数 1615 浏览 8 评论 0原文

概述
使用

  • 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

问题

  1. CGLib 无法代理最终类
  2. CGLib 需要默认(空)构造函数
  3. 某些服务需要通过 JMX
  4. MBean 导出器公开,除非由 CGLib 代理,否则无法工作
  5. 某些 @Transactional @Service< /code> 通过外观服务进行访问,该服务需要在外观事务中包含多个服务(例如超过 2 个应用程序组件的观察者服务)
  6. 某些接口具有多个实现(当前通过 @Qualifier 来区分) >)
  7. 未来指南(或者最好有功能) - 每个应用程序模块将有 beanRefContext.xml 文件来配置其内部应用程序上下文

当我使用 XML 配置时,我能够强制执行所有指南我在上面介绍过,但是当切换到注释时,Spring 似乎行为不当。
我小组中的开发人员更喜欢注释配置(我似乎更容易连接和编写新代码),但我注意到他们在代码中引入了各种“黑客”,以防止处理 Spring 应用程序上下文故障。

问题

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

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) {...})
  • 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

  1. CGLib can't proxy final classes
  2. CGLib requires default (empty) constructor
  3. Some services are required to be exposed via JMX
  4. MBean exporter can't work unless proxied by CGLib
  5. Some @Transactional @Services 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)
  6. Some interfaces have more than one implementation (which currently distinguished by @Qualifier)
  7. 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)

  1. 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
  2. Is there a way of stop working with CGLib, keep the annotation configuration and still be able to export my MBeans with annotations?
  3. What is the suitable implementation for keeping most (preferably, all) of my guidelines?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

只是我以为 2024-10-12 14:48:02

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

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

上述步骤还使我能够减少 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:

  • Each dependent project (Maven module) has it's own ApplicationContext
  • Every dependent project application context is defined in beanRefContext.xml
  • These application contexts are loaded in hierarchy using Spring context hierarchy mechanism.
    • This step is actually not fully supported by Spring and requires additional work
  • Since my application is layered, I could disable CGLib on all my modules besides the JMX layer (I can live with it :-) ).

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.

我不会写诗 2024-10-12 14:48:02

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

Answer to point 2)
You could use AspectJ instead of CGLib.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文