spring为什么转换到接口而不是转换到java类?
我遇到了一些spring框架中使用的java类。首先,applicationContext中有bean。xml
<bean id="someBean" parent="txProxyTemplate">
<property name="target">
<bean class="path.to.bean.impl.SomeBeanImpl">
...
</bean>
...
</bean>
我有接口ISomeBean
,以及它的实现SomeBeanImpl
然后,我有另一个使用ISomeBean的类
public class SomeOtherClass {
...
public function doStuff() {
...
ApplicationContext ctx;
SomeBean theBean = (SomeBean) ctx.getBean;
}
}
我想知道为什么我们要转换到一个接口,而不是转换到类
# 1 楼答案
为什么要将
SomeOtherClass
与特定的实现联系起来?使用该接口,您可以获得松散耦合——您可以针对一个伪实现进行测试,或者稍后切换到另一个实现这是控制反转的很大一部分好处——您与依赖项的耦合不像直接在类中实例化它们那样紧密
# 2 楼答案
依赖注入框架有两个目标:
如果你对1和2都不感兴趣,显然你不需要依赖注入:只需自己创建bean
SombeBeanImpl = new SomeBeanImpl()
如果你只对1感兴趣,而对2不感兴趣,你可以把你得到的bean转换成
SomeBeanImpl
,但是你一定会一直使用它。我怀疑有一种方法可以在Spring中指定您只有一个实现,而没有接口,但我不确定如果你对2感兴趣,根据定义,你也对1感兴趣。实际上,如果不想明确地说明要实例化的具体类,可以将其委托给控制对象创建的factory。这就是依赖注入框架实际上是什么,一个复杂的工厂
# 3 楼答案
您可以强制转换到接口,以保持代码的通用性和松散耦合。一旦您将一个对象强制转换为一个具体的类,您就在您的对象和它的合作者之间添加了一个紧密耦合。如果合作者的类类型发生更改,那么对象的强制转换操作可能会中断,从而导致ClassCastException。如果我们使用接口,您可以自由地更改协作者的实现类类型,而不必担心对客户端的影响
# 4 楼答案
使用依赖注入的一大好处是,类不必知道使用了哪个实现,只需要一个实现。因此,将其转换为接口是有意义的
然而,你不应该把它与能做或不能做的事情混为一谈
# 5 楼答案
这种类型的演员阵容背后的逻辑是给春季国际奥委会和依赖注入带来自由。使用这种方法的好处之一是类之间的耦合非常松散
例如,在你的情况下,如果某个晴朗的早晨你决定更改ISomeBeanImpl的代码,只要功能不变,你就不需要更改任何其他内容
看看Spring IOC documentation,想法会更清楚
# 6 楼答案
还有它的风格方面——松散耦合等等
更具体地说: 如果您使用的是AOP(Spring默认为许多内置功能提供AOP,例如事务支持)和cglib代理,那么实际的bean将不是实现类,而是动态创建的代理类。在这种情况下,您的应用程序将失败,并出现各种类似ClassCast的异常。如果你在春天做出的改变无意中激活了代理行为,这可能会让你大吃一惊