不自动装配限制IoC的目标吗?

时间:2010-12-17 14:02:55

标签: java spring java-ee autowired

IoC很不错,但是用于自动装配(@EJB,@ Autowired,@ Inject,@ SpringBean ......),您认为它不会限制IoC的目标吗?

实际上我不太了解不同框架中的自动装配系统,但似乎它主要基于类型。

当你在IService上使用@EJB时,你需要只有一个实现ServiceImpl来使它工作。

如果我们想要很多实现怎么办?

似乎一些自动装配注释可以有参数。 例如Stripes,您可以这样做: @SpringBean( “xxxService”) 其中xxxService是一个spring初始化bean。

在这种情况下,你不要做“new XxxServiceImpl()” 但是您仍然对要在bean中使用的服务实现进行硬编码引用。它不是类引用,而是实现的Spring bean引用......

你怎么看? 我喜欢自动装配,但只是想知道自己......

4 个答案:

答案 0 :(得分:6)

是的,自动装配存在限制(只是自动连接接口的一个实现),因此在注入正确的实现时,它会破坏IoC灵活性的一部分。

但是,我认为自动装配只是减少配置的一种方法。因此,当90%的依赖项可以自动装配时,您最终会得到更少的配置(剩下的配置很重要,因为它只包含重要的(特定于实现的)位)

答案 1 :(得分:2)

我怀疑这可以被视为一个客观的问题,但让我们来看看。

我对此有过一些讨论,当然不仅仅是你这样想。

是的,这样做会让IoC毫无意义。它仍然更容易,因为您不必自己弄清楚理想的接线顺序,但是您失去了通过更改配置文件来切换实现的优势,这是我们首先开始使用IoC的原因之一。

现在似乎有两种主要方法可以在实现之间切换:

  1. 使用限定符
  2. 您可以在实现中添加注释,在注入点上添加另一个注释,这将告诉容器您要使用哪个注释。您仍然需要在两个位置更改代码,因此它与实现子接口和按类型布线相同。它仍然是硬编码的。

    1. 使用beanconfigurer
    2. 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
}

希望这能解决你的问题。