13

我是 Spring 新手并使用 Spring 3.2.2。我有一些注入的豆子,<constructor-arg>效果很好。现在我想注入一些@Autowired完全出错的bean。我已经这样做了:

豆类.xml:

<context:annotation-config />
<bean id="formulaFactory" class="my.project.formula.impl.GenericFormulaFactory"
    factory-method="getInstance">
<qualifier value="formulaFactory"></qualifier>
</bean>

Java源码:

@Autowired
@Qualifier("formulaFactory")
private FormulaFactory formulaFactory;

(更改限定符或将其排除在外没有任何区别......)

我得到这个错误:

java.lang.LinkageError: loader constraint violation: loader (instance of org/springframework/context/support/ContextTypeMatchClassLoader$ContextOverridingClassLoader) previously initiated loading for a different type with name "my/project/formula/FormulaKey"

我想知道为什么会出现这个错误。尤其是那种类型FormulaKey让我很恼火。当我将@Autowired注释与其他 bean 一起使用时,它可以工作。

我不得不提一下,我通过getInstance方法将 GenericFormulaFactory 实现为单例。也许这会导致一些问题?

该应用程序是一个独立的应用程序。我也检查了所有 jar 的重复性,我不认为这是问题的原因,因为错误与我自己的类有关。

问候,奥利弗

更新: 我在不知道是什么原因的情况下删除了错误。

我做了什么:

  1. 移除工厂实现的 getInstance() 方法和单例性质
  2. 将工厂接口添加到处理程序类构造函数(以及constructor-arg在 xml 中)

现在我可以使用 xml 来配置实现并将其与@Autowired注释一起使用。

xml:

<bean id="formulaHandler" class="my.project.formula.impl.DefaultFormulaHandler">
    <constructor-arg ref="formulaFactory" />
</bean>
<bean id="formulaFactory" class="my.project.formula.impl.GenericFormulaFactory" />

仍然想知道为什么首先出现错误。在工厂的实现中,aHashMap是使用FormulaKeyas 键创建的,所以这可能会造成麻烦。如果有人知道答案,我真的很想知道。

4

1 回答 1

36

到目前为止,我可以收集到以下信息:

  1. java.lang.LinkageError当加载一个类时涉及两个类加载器时,会出现错误。
  2. 类加载器通过生成包含完全限定类名本身和加载它的类加载器的唯一标识符来跟踪加载的类。
  3. 当类加载器接收到由另一个类加载的类的引用时,该类已经被自己加载,这会导致错误的情况,因为在类加载层次结构中,一个类只能加载一次。
  4. 当涉及到自定义类加载器时,为了加载特定的类,实践是如果该类已经加载,则首先查询父类加载器。
  5. 在这种情况下,当自定义类加载器不查询父层次结构并决定加载类本身时,可能存在正在加载的类已由父层次结构中的某个类加载器加载的情况。
  6. 阅读 Kieviet, Frank 的The java.lang.LinkageError: loader constraint violation”demystified以了解更多信息。
  7. 对于您的情况,我猜 XML 配置和注释处理是由两个不同的类加载器完成的。
  8. 在错误场景中,my.project.formula.FormulaKey由一个类加载器加载,然后参与注释处理的类加载器再加载一次。
  9. 当您更改代码时,加载将my.project.formula.FormulaKey延迟,因为在从 XML 加载上下文时不再引用它。
于 2013-08-19T13:43:06.420 回答