3

私は次のクラスを持っています:

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

何がうまくいかないのですか?

<aop:scoped-proxy/>Bean 宣言からを削除すると、機能します。

更新: にデフォルトのコンストラクターを配置するとMS3BusinessModule、機能します。デフォルトのコンストラクターが必要な理由がわかりません。誰か説明してください。

4

1 に答える 1

4

MS3BusinessModule に既定のコンストラクターを配置すると、機能します。デフォルトのコンストラクターが必要な理由がわかりません。誰か説明してください。

動作する方法<aop:scoped-proxy/>は、「実際の」Bean を別の名前で隠し、実際の Bean のクラスのサブクラスであり、すべてのメソッド呼び出しをターゲット Bean の正しいインスタンスに委譲する CGLIB プロキシ クラスを作成することです。したがって、ここには 2 種類のオブジェクトがあります。

  • com.hba.MS3BusinessModule各セッション/リクエスト/スコープが何であれ、のnインスタンス、および
  • 動的に生成されたプロキシ クラスの 1 つのシングルトン インスタンス。

nターゲット Bean は、引数を取るコンストラクターを使用して構築され、<constructor-arg>値が渡されますが、プロキシ クラスには、呼び出す引数のないスーパークラス コンストラクターが必要です (もちろん、protectedではなく宣言できますpublic)。プロキシ メカニズムは、プロキシ インスタンスのスーパークラス メソッドを実際に呼び出すことはありません。代わりに、すべての呼び出しがターゲット インスタンスに送られるためですinstanceof。タイプ。

別の修正方法は、実装するインターフェースを提供しM3BusinessModule、他の Bean によるこの Bean へのすべての参照で、具象クラス タイプではなくインターフェース タイプを使用することです。これにより、Springjava.lang.reflectは CGLIB の代わりにプロキシを使用し、具体的なクラスを拡張する必要なくインターフェースを実装できます。

于 2013-03-27T17:28:48.653 に答える