简体   繁体   English

在Spring 3.1中实例化bean时出错

[英]Error in instantiating bean in Spring 3.1

I have the following classes: 我有以下课程:

public abstract class AbstractBusinessModule {

}

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

    }
}

And the following bean declarations: 以下bean声明:

<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

What could be going wrong? 怎么可能出错?

If I remove the <aop:scoped-proxy/> from the bean declaration it works. 如果我从bean声明中删除<aop:scoped-proxy/>它可以工作。

Update: If I put a default constructor in MS3BusinessModule , it works. 更新:如果我在MS3BusinessModule放置一个默认构造MS3BusinessModule ,它可以工作。 I do not understand the reason why a default constructor is required. 我不明白为什么需要默认构造函数。 can somebody explain please. 请有人解释一下。

If I put a default constructor in MS3BusinessModule, it works. 如果我在MS3BusinessModule中放置一个默认构造函数,它就可以工作。 I do not understand the reason why a default constructor is required. 我不明白为什么需要默认构造函数。 can somebody explain please. 请有人解释一下。

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. <aop:scoped-proxy/>工作方式是以不同的名称隐藏“真正的”bean并创建一个CGLIB代理类,它是真实bean类的子类,并将所有方法调用委托给正确的实例目标bean的。 So you have two different kinds of object here: 所以你在这里有两种不同的对象:

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

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 ). 使用带有参数的构造函数构造n个目标bean,并将<constructor-arg>值传递给它,但代理类需要一个no-arg超类构造函数来调用(当然可以声明为protected而不是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. 代理机构将永远不会真正调用任何代理实例的超类方法的所有调用转到目标实例(S)代替,但代理类需要为了扩展目标bean类代理是一个instanceof的正确的类型。

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. 另一种解决方法是提供M3BusinessModule实现的接口M3BusinessModule其他bean对此的所有引用都使用接口类型而不是具体的类类型。 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使用java.lang.reflect代理而不是CGLIB代理,实现接口而无需扩展具体类。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM