IoC很不错,但是用于自动装配(@EJB,@ Autowired,@ Inject,@ SpringBean ......),您认为它不会限制IoC的目标吗?
实际上我不太了解不同框架中的自动装配系统,但似乎它主要基于类型。
当你在IService上使用@EJB时,你需要只有一个实现ServiceImpl来使它工作。
如果我们想要很多实现怎么办?
似乎一些自动装配注释可以有参数。 例如Stripes,您可以这样做: @SpringBean( “xxxService”) 其中xxxService是一个spring初始化bean。
在这种情况下,你不要做“new XxxServiceImpl()” 但是您仍然对要在bean中使用的服务实现进行硬编码引用。它不是类引用,而是实现的Spring bean引用......
你怎么看? 我喜欢自动装配,但只是想知道自己......
答案 0 :(得分:6)
是的,自动装配存在限制(只是自动连接接口的一个实现),因此在注入正确的实现时,它会破坏IoC灵活性的一部分。
但是,我认为自动装配只是减少配置的一种方法。因此,当90%的依赖项可以自动装配时,您最终会得到更少的配置(剩下的配置很重要,因为它只包含重要的(特定于实现的)位)
答案 1 :(得分:2)
我怀疑这可以被视为一个客观的问题,但让我们来看看。
我对此有过一些讨论,当然不仅仅是你这样想。
是的,这样做会让IoC毫无意义。它仍然更容易,因为您不必自己弄清楚理想的接线顺序,但是您失去了通过更改配置文件来切换实现的优势,这是我们首先开始使用IoC的原因之一。
现在似乎有两种主要方法可以在实现之间切换:
您可以在实现中添加注释,在注入点上添加另一个注释,这将告诉容器您要使用哪个注释。您仍然需要在两个位置更改代码,因此它与实现子接口和按类型布线相同。它仍然是硬编码的。
Spring有这个bean配置概念,它只是替换旧的xml文件。您可以在某个类中处理配置,该类将告诉容器如何连接。我没有看到相对于旧样式的优势(因为这个原因,xml语法更具可读性),但我想这是一个品味问题。
对我而言,以类似的方式使用类型自动装配的唯一方法是使用类路径,这样您就可以通过包含不同的类来弹出模拟而不是实现。但是由于java classpath具有这样一个用户友好的界面,我也不认为这比旧的xml方式更容易。
所以最后,我认为这一切都归结为品味问题。是的,使用注释进行自动装配要容易得多,但它会将您的配置硬编码到代码中,就像您说的那样。问题是,它是否真的改变了,它通常保证采用“软编码”方法?
答案 2 :(得分:2)
响应注释,是语义bean名称的示例,而不是“usedService”和“notUsedService”。一个普通的系统会在服务器之间分割一些数据,但有些数据只存储在一个地方。
@Autowired
@Qualifier("customerDataSource")
DataSource ds;
@Autowired
@Qualifier("geoipDataSource")
DataSource geoip;
并在xml中:
<bean id="customerDataSource" class="...ShardedDataSource">
<property name="dataSources">
<list>
<value><ref local="ds1"/>
<value><ref local="ds2"/>
</list>
</property>
</bean>
<bean id="ds1" class="...DataSource">
...
</bean>
<bean id="ds2" class="...DataSource">
...
</bean>
<alias name="ds2" alias="geoipDataSource"/>
答案 3 :(得分:0)
您可以尝试autowiring by name。这将解决您的问题。
如果您对类型的自动装配有严格要求。然后你可以这样指定,
<bean id="PersonBean1" class="com.mkyong.common.Person">
<property name="name" value="mkyong1" />
<property name="address" value="address 1" />
<property name="age" value="28" />
</bean>
<bean id="PersonBean2" class="com.mkyong.common.Person">
<property name="name" value="mkyong2" />
<property name="address" value="address 2" />
<property name="age" value="28" />
</bean>
您可以在类中指定bean,如
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
public class Customer
{
@Autowired
@Qualifier("PersonBean1")
private Person person;
private int type;
private String action;
//getter and setter methods
}
希望这能解决你的问题。