在 Spring 3.1 中实例化 bean 时出错 [英] Error in instantiating bean in Spring 3.1

查看:25
本文介绍了在 Spring 3.1 中实例化 bean 时出错的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下课程:

public abstract class AbstractBusinessModule {

}

public class MS3BusinessModule extends AbstractBusinessModule 
{
    public MS3BusinessModule(SomeOtherClass value)
    {

    }
}

以及以下 bean 声明:

And the following bean declarations:

<bean id="ms3BusinessModule" class="com.hba.MS3BusinessModule" >
    <constructor-arg index="0">
        <ref bean="someOtherBeanID"/>
    </constructor-arg>
    <aop:scoped-proxy />
</bean>

在我的应用程序启动时,我收到以下错误:

Upon startup of my application I get the following error:

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ms3BusinessModule' defined in BeanDefinition defined in class path resource [spring.xml]: Initialization of bean failed; nested exception is org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.hba.MS3BusinessModule]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:527)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:293)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:290)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:192)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:567)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:895)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:425)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.hba.EhCacheTest.main(EhCacheTest.java:16)
Caused by: org.springframework.aop.framework.AopConfigException: Could not generate CGLIB subclass of class [class com.hba.MS3BusinessModule]: Common causes of this problem include using a final class or a non-visible class; nested exception is java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:212)
    at org.springframework.aop.framework.ProxyFactory.getProxy(ProxyFactory.java:112)
    at org.springframework.aop.scope.ScopedProxyFactoryBean.setBeanFactory(ScopedProxyFactoryBean.java:109)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeAwareMethods(AbstractAutowireCapableBeanFactory.java:1439)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1408)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:519)
    ... 11 more
Caused by: java.lang.IllegalArgumentException: Superclass has no null constructors but no arguments were given
    at net.sf.cglib.proxy.Enhancer.emitConstructors(Enhancer.java:721)
    at net.sf.cglib.proxy.Enhancer.generateClass(Enhancer.java:499)
    at net.sf.cglib.transform.TransformingClassGenerator.generateClass(TransformingClassGenerator.java:33)
    at net.sf.cglib.core.DefaultGeneratorStrategy.generate(DefaultGeneratorStrategy.java:25)
    at net.sf.cglib.core.AbstractClassGenerator.create(AbstractClassGenerator.java:216)
    at net.sf.cglib.proxy.Enhancer.createHelper(Enhancer.java:377)
    at net.sf.cglib.proxy.Enhancer.create(Enhancer.java:285)
    at org.springframework.aop.framework.Cglib2AopProxy.getProxy(Cglib2AopProxy.java:200)
    ... 16 more

可能出了什么问题?

如果我从 bean 声明中删除 <aop:scoped-proxy/> 它将起作用.

If I remove the <aop:scoped-proxy/> from the bean declaration it works.

更新:如果我在 MS3BusinessModule 中放置一个默认构造函数,它就可以工作.我不明白为什么需要默认构造函数.谁能解释一下.

Update: If I put a default constructor in MS3BusinessModule, it works. I do not understand the reason why a default constructor is required. can somebody explain please.

推荐答案

如果我在 MS3BusinessModule 中放置一个默认构造函数,它就可以工作.我不明白为什么需要默认构造函数.谁能解释一下.

If I put a default constructor in MS3BusinessModule, it works. I do not understand the reason why a default constructor is required. can somebody explain please.

<aop:scoped-proxy/> 的工作方式是以不同的名称隐藏真实"bean 并创建一个 CGLIB 代理类,它是真实 bean 的子类类,并将所有方法调用委托给目标 bean 的正确实例.所以这里有两种不同类型的对象:

The way <aop:scoped-proxy/> works is to hide away the "real" bean under a different name and create a CGLIB proxy class which is a subclass of the real bean's class, and which delegates all method calls to the correct instance of the target bean. So you have two different kinds of object here:

  • ncom.hba.MS3BusinessModule 实例,用于每个会话/请求/无论范围是什么,以及
  • 动态生成的代理类的一个单例实例.
  • n instances of com.hba.MS3BusinessModule for each session/request/whatever the scope is, and
  • one singleton instance of the dynamically generated proxy class.

n 目标 bean 是使用带参数的构造函数构造的,您的 <constructor-arg> 值传递给它,但代理类需要一个 no-arg 要调用的超类构造函数(当然可以声明为 protected 而不是 public).代理机制永远不会真正调用代理实例上的任何超类方法,因为所有调用都转到目标实例,但代理类需要扩展目标 bean 类,以便代理成为 instanceof 正确的类型.

The n target beans are constructed using the constructor that takes arguments, with your <constructor-arg> values passed to it, but the proxy class needs a no-arg superclass constructor to call (which could of course be declared protected rather than public). The proxy mechanism will never actually call any of the superclass methods on the proxy instance as all calls go to the target instance(s) instead, but the proxy class needs to extend the target bean class in order for the proxy to be an instanceof the right type.

另一种解决方法是提供一个 M3BusinessModule 实现的接口,并使其他 bean 对这个 bean 的所有引用都使用接口类型而不是具体的类类型.这将允许 Spring 使用 java.lang.reflect 代理而不是 CGLIB 代理,实现接口而无需扩展具体类.

An alternative fix is to provide an interface that M3BusinessModule implements, and make all references by other beans to this one use the interface type rather than the concrete class type. This will allow Spring to use a java.lang.reflect proxy instead of a CGLIB one, implementing the interface without needing to extend the concrete class.

这篇关于在 Spring 3.1 中实例化 bean 时出错的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆