在Spring 3.1中实例化bean时出错

时间:2013-03-27 17:07:40

标签: java spring aop spring-aop

我有以下课程:

public abstract class AbstractBusinessModule {

}

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

    }
}

以下bean声明:

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

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

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/>,它就可以工作。

更新:如果我在MS3BusinessModule中放置一个默认构造函数,它就可以了。我不明白为什么需要默认构造函数。请有人解释一下。

1 个答案:

答案 0 :(得分:4)

  

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

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

  • n 每个会话/请求的com.hba.MS3BusinessModule个实例/无论范围是什么,
  • 动态生成的代理类的一个单例实例。

n 目标bean是使用带参数的构造函数构造的,并且传递了<constructor-arg>个值,但代理类需要一个无参数的超类构造函数来调用(当然可以声明protected而不是public)。代理机制永远不会实际调用代理实例上的任何超类方法,因为所有调用都转到目标实例,但代理类需要扩展目标bean类,以使代理成为{{ 1}}正确的类型。

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