我是 Spring 新手并使用 Spring 3.2.2。我有一些通过 <constructor-arg>
注入(inject)的 bean 效果很好。现在我想通过 @Autowired
注入(inject)一些 bean这完全出错了。我已经这样做了:
beans.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 的重复性,我不认为这是问题的原因,因为错误与我自己的类有关。
问候, 奥利弗
更新: 我在不知道是什么原因的情况下删除了错误。
我做了什么:
- 删除工厂实现的 getInstance() 方法和单例性质
- 将工厂接口(interface)添加到处理程序类构造函数(以及 xml 中的
constructor-arg
)
现在我可以使用 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" />
仍然想知道为什么首先会出现错误。在工厂执行中,一个HashMap
使用 FormulaKey
创建作为关键,所以也许这会引起麻烦。如果有人知道答案,我真的很想知道。
最佳答案
到目前为止,我可以收集到以下信息:
- 错误
java.lang.LinkageError
出现在加载一个类时涉及两个类加载器的情况。 - 类加载器通过生成一个唯一标识符来跟踪加载的类,该标识符包含完全限定的类名本身和加载它的类加载器。
- 当类加载器接收到由另一个类加载的类的引用时,该类已被自己加载,这会导致错误情况,因为在类加载层次结构中,一个类只能加载一次。
- 当涉及到自定义类加载器时,为了加载特定类,实践是如果该类已经加载,则首先查询父类加载器。
- 在这种情况下,当自定义类加载器不查询父层次结构并决定加载类本身时,可能会出现正在加载的类已由父层次结构中的某个类加载器加载的情况。
- 阅读 Kieviet, Frank 的 "The java.lang.LinkageError: loader constraint violation" demystified"了解更多信息。
- 对于您的情况,我猜 XML 配置和注释处理是由两个不同的类加载器完成的。
- 在错误场景中,
my.project.formula.FormulaKey
由一个类加载器加载,然后涉及注解处理的类加载器再加载一次。 - 当您更改代码时,
my.project.formula.FormulaKey
的加载将被延迟,因为在从 XML 加载上下文时不再引用它。
关于java - Spring java.lang.LinkageError : loader constraint violation: loader previously initiated loading for a different type with name X,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18127431/