java 'bean 实例化失败;它是一个抽象类吗?尝试使用抽象父级实例化 bean 时

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30625320/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 17:23:55  来源:igfitidea点击:

'Instantiation of bean failed; Is it an abstract class?' When trying to instantiate a bean with an abstract parent

javaspringspring-mvchybris

提问by Juliano A. Felipe

I'm trying to instantiate a bean, without a class definition, on Spring context by inheriting a parent bean, which is abstract. Like this:

我试图通过继承一个抽象的父 bean 在 Spring 上下文中实例化一个 bean,没有类定义。像这样:

<bean id="childBean" parent="abstractBean">
    ...
</bean>

<bean id="abstractBean" class="com.java.bean.AbstractBeanClass" 
        abstract="true" />

But Spring is giving me the following error message:

但是 Spring 给了我以下错误消息:

Error creating bean with name 'childBean' defined in class path resource 
    [project-spring.xml]: 
Instantiation of bean failed; nested exception is 
    org.springframework.beans.BeanInstantiationException: 
Could not instantiate bean class [com.java.bean.AbstractBeanClass]: 
Is it an abstract class?;
nested exception is java.lang.InstantiationException
...

I remember having this in another project, and it works perfectly.
I remember having this in the same project, and it works perfectly.

我记得在另一个项目中使用过它,并且效果很好。
我记得在同一个项目中使用过它,并且效果很好。

What am I missing here?

我在这里错过了什么?

UPDATE 1Found another bean being intatiated exactly like the way I mentioned:

更新 1发现另一个 bean 与我提到的方式完全一样:

<bean id="variantOptionDataConverter" parent="abstractPopulatingConverter">
    ...
</bean>

UPDATE 2
Declaration of the Abstract class:

更新 2
抽象类的声明:

public abstract class AbstractBeanClass<SOURCE, TARGET>
        extends AbstractConverter<SOURCE, TARGET>
        implements PopulatorList<SOURCE, TARGET>
{
...
}

Note: There's other classes that extends this class. None of the "other spring beans that works" I mentioned above extends this class.

注意:还有其他类扩展了这个类。我上面提到的“其他有效的 spring bean”都没有扩展这个类。

Note 2: I know that it's weird, and, by Java fundamentals, it should not work (like everyone mentioned). But, I don't know how, the other Spring beans are being put in the context. I tried to copy the "other spring beans that work" into my code, change some duplicated names, and it worked. And, that's what I'm trying to understand...

注 2:我知道这很奇怪,而且根据 Java 基础,它不应该工作(就像每个人都提到的那样)。但是,我不知道如何将其他 Spring bean 放入上下文中。我试图将“其他有效的 spring bean”复制到我的代码中,更改一些重复的名称,并且成功了。而且,这就是我想要理解的......

采纳答案by Juliano A. Felipe

Found the answer:

找到答案:

Indeed, like Sotirios Delimanoliscommented, "You must have something else going on, proxying of some kind maybe", Spring has a proxy that instantiate this type of bean declaration, but it can't instantiate the bean without its methods (which are just declared in the abstract class, not implemented).
So you must "implement" these methods, like this:

确实,就像Sotirios Delimanolis评论的那样,“你必须有别的事情发生,也许是某种代理”,Spring 有一个代理来实例化这种类型的 bean 声明,但是它不能在没有方法的情况下实例化 bean(这些方法只是在抽象类中声明,未实现)。
所以你必须“实现”这些方法,像这样:

<bean id="childBean" parent="abstractBean">
   <lookup-method name="notImplementedMethod" bean="anotherBean"/>
</bean>

The anotherBeanmust be the same type as notImplementedMethod.

anotherBean必须是同一类型notImplementedMethod

回答by Sebastian

This concrete example Juliano is referring to is from the hybris commerce suite. Hybris has the concept of extensions that have dependencies on each other. Each extension defines their own application context which has access to its inherited application contexts (from those extensions that are declared as dependencies).

Juliano 所指的这个具体示例来自 hybris 商务套件。Hybris 具有相互依赖的扩展的概念。每个扩展定义了它们自己的应用上下文,它可以访问其继承的应用上下文(来自那些被声明为依赖项的扩展)。

In this example there is an abstractPopulatingConverter bean declaration declared at the root application context where its declared java class is abstract. However, in other application context further down the dependency tree there is an alias definition for this "abstractPopulatingConverter" that points to a bean definitions with a concrete class. That's why in a lot of cases (namely the ones that are even further down the dependency tree) using the parent="abstractPopulatingConverter" works as it points to the new bean defined by the alias.

在此示例中,在根应用程序上下文中声明了一个 abstractPopulatingConverter bean 声明,其中其声明的 java 类是抽象的。但是,在依赖树更下方的其他应用程序上下文中,此“abstractPopulatingConverter”有一个别名定义,它指向具有具体类的 bean 定义。这就是为什么在很多情况下(即在依赖关系树更靠后的情况下)使用 parent="abstractPopulatingConverter" 的原因,因为它指向由别名定义的新 bean。

回答by Dmitry Nikiforov

This is the very common message when Spring container faces with absatract Java class (not abstract bean). Check your com.java.bean.AbstractBeanClass code and probably you can find "public abstract class".

这是 Spring 容器面对抽象 Java 类(不是抽象 bean)时非常常见的消息。检查您的 com.java.bean.AbstractBeanClass 代码,您可能会找到“公共抽象类”。

回答by Sotirios Delimanolis

What am I missing here?

我在这里错过了什么?

I don't know what's going on in your other project, but Spring cannot instantiate beans for classes that are abstract.

我不知道您的其他项目中发生了什么,但是 Spring 无法为abstract.

Concerning abstractbeans, the Spring documentationstates

关于abstractbean,Spring 文档指出

A child bean definition inherits configuration data from a parent definition.

[...]

A child bean definition uses the bean class from the parent definition if none is specified, but can also override it. In the latter case, the child bean class must be compatible with the parent, that is, it must accept the parent's property values.

子 bean 定义从父定义继承配置数据。

[...]

如果没有指定,子 bean 定义使用父定义中的 bean 类,但也可以覆盖它。在后一种情况下,子 bean 类必须与父级兼容,即它必须接受父级的属性值。

In other words, an bean definition declared with abstract="true"is simply used as a template for other beans.

换句话说,用 with 声明的 bean 定义abstract="true"只是用作其他 bean 的模板。

Java does not allow instantiation of abstractclasses. Spring cannot overrule this language feature. Spring cannot instantiate beans of abstractclass types.

Java 不允许abstract类的实例化。Spring 不能推翻这个语言特性。Spring 不能实例化abstract类类型的bean 。