为什么 Java 框架不强制使用接口?
我只是想知道,为什么没有 Spring Bean 或 EJB Bean(或 OSGi 服务)的接口?我知道没有必要这样做,因为框架可以使用反射 API 来调用方法,但是如果使用接口来代替,错误不是会少一些吗?
例如,为什么 OSGi 组件没有如下所示的接口:
interface OSGIComponent {
void activate(BundleContext context);
...
}
I was just wondering, why there is no interface for a Spring Bean or for a EJB Bean (or for an OSGi service)? I know that there is no need for this because frameworks can use reflection API for calling methods but wouldn't it be less erroneus if interfaces were used instead?
For example, why there is no interface for OSGi component which would look like this:
interface OSGIComponent {
void activate(BundleContext context);
...
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
对于 Spring,您不必实现特定于 Spring 的接口即可在代码中使用 Spring。这实际上被视为一个优点:它可以防止您的代码与 Spring 绑定,从而使其更加可移植。
这并不是说您不能实现 Spring 特定的接口。我想到的一个例子(没有双关语)是
InitializingBean
;这定义了一个方法,afterPropertiesSet()
,它在 Spring 实例化您的 bean 并设置其所有属性后被调用(顾名思义)。因此,您通常可以使用特定于框架的接口和类;您必须在保持代码可移植性与利用框架提供的有用内容之间取得平衡。
您给出了可能实现
OSGIComponent
接口的 OSGi 组件的示例。 Spring 实际上有一个接口,您的类可以实现该接口来传递对包含 Spring 上下文的引用:ApplicationContextAware
。不过,通常情况下,您不需要使用这些特定于框架的接口。如果您的代码只关注实际的业务逻辑,而不是框架如何实例化对象、将对象连接在一起等细节,那么它通常更容易理解。In the case of Spring, you don't have to implement a Spring-specific interface to be able to use Spring with your code. This is actually seen as an advantage: it prevents your code being tied to Spring, therefore making it more portable.
That's not to say that you can't implement Spring-specific interfaces. One example that springs to mind (no pun intended) is
InitializingBean
; this defines a method,afterPropertiesSet()
, which gets called (as the name suggests) after Spring has instantiated your bean and set all of its properties.So there are often framework-specific interfaces and classes that you can use; you have to balance keeping your code portable with making use of the useful stuff that frameworks provide.
You gave the example of an OSGi component that might implement an
OSGIComponent
interface. Spring does in fact have an interface that your class can implement to be passed a reference to the containing Spring context:ApplicationContextAware
. Typically, though, you don't need to make use of these framework-specific interfaces. Your code is generally easier to understand if it just focuses on the actual business logic, rather than details of how the framework is instantiating objects, wiring objects together, and so on.在第三版之前,EJB 标准“强制使用接口”。事实上,每个 bean 必须至少有两个(通常是三个)接口(主接口、远程接口和本地接口)。除了实现类没有实现这些接口,并且您必须有一个 XML 部署描述符将所有内容连接在一起,如果有任何内容不合适(例如,由于拼写错误),您会得到一个完全神秘的运行时错误。这绝对是一场噩梦,尽管这个错误在几年前就被修复了,但 EJB 至今仍享有可怕的声誉。
这根本没有意义。
接口并不是使代码“更少错误”的神奇仙尘。如果您的 API 可能有多个实现,则您可以创建一个接口。否则你就不会。就是这样。
Before version three, the EJB standard did "enforce use of interfaces". In fact, you had to have at least two, often three interfaces for each bean (Home, Remote and Local). Except the implementation classes didn't implement those interfaces and you had to have an XML deployment descriptor that connected everything together and if anything didn't fit (e.g. because of a typo) you got a completely cryptic runtime error. It was an absolute nightmare, and EJBs have a horrible reputation to this day, even though this mistake was fixed years ago.
That makes no sense at all.
Interfaces aren't magic fairy dust that makes code "less erroneous". If you have an API that may have several implementations, you create an interface. Otherwise you don't. That's it.
如果bean必须实现一个接口,那么该接口必须存在于类路径中,导致bean依赖于正在使用的依赖注入框架(至少在JSR-330中依赖注入注释标准化之前,现在我们想要向后兼容性)。
然而,在 Spring 中,bean可能实现与容器交互的接口,例如
InitializingBean
和DisposableBean
。 (来源)If the beans have to implement an interface, that interface must be present in the classpath, causing the bean to depend on the dependency injection framework in use (at least prior to the standardization of dependency injection annotations in JSR-330, and now we want backwards compatibility).
However, in Spring, beans may implement an interfaces to interact with the container, for instance
InitializingBean
andDisposableBean
. (source)