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

查看:153
本文介绍了在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:

    每个会话/请求/范围内,com.hba.MS3BusinessModule
  • n 个实例,以及
  • 动态生成的代理类的一个单例实例.
  • 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类,以使代理成为正确的类型.

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对此接口的所有引用都使用接口类型而不是具体的类类型.这将允许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天全站免登陆