10

循環依存を避けるため@Autowiredに、コンストラクターの代わりにセッターで使用できることを読みました。

もしそうなら、なぜこれは失敗するのですか?

@Component
private static class A {
    @Autowired
    public A(B b) {
    }
}

@Component
private static class B {
    private A a;

    public B() {
    }

    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}

Aと同様にクラスを定義するとB、すべて問題ありませんが、上記のクラスはすでに機能しているはずですが、なぜ機能しないのでしょうか。Aクラスのコンストラクターの依存関係を取り除くことができない状況にあります。この場合、私は何ができますか?

編集:私はSpring3.2.1.RELEASEを使用しています

EDIT2:私の例外:

Exception in thread "main" org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dependencyTest.A' defined in file [/home/adam/workspaces/testproject/target/classes/mypackage/test/DependencyTest$A.class]: Unsatisfied dependency expressed through constructor argument with index 0 of type [mypackage.test.DependencyTest$B]: : Error creating bean with name 'dependencyTest.B': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void mypackage.test.DependencyTest$B.setA(mypackage.test.DependencyTest$A); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dependencyTest.A': Requested bean is currently in creation: Is there an unresolvable circular reference?; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dependencyTest.B': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void mypackage.test.DependencyTest$B.setA(mypackage.test.DependencyTest$A); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dependencyTest.A': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:730)
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:196)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1049)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479)
    at org.springframework.context.annotation.AnnotationConfigApplicationContext.<init>(AnnotationConfigApplicationContext.java:84)
    at mypackage.test.DependencyTest.main(DependencyTest.java:10)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dependencyTest.B': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void mypackage.test.DependencyTest$B.setA(mypackage.test.DependencyTest$A); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dependencyTest.A': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:288)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1120)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:891)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:834)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:795)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:723)
    ... 14 more
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void mypackage.test.DependencyTest$B.setA(mypackage.test.DependencyTest$A); nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dependencyTest.A': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:601)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:285)
    ... 26 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'dependencyTest.A': Requested bean is currently in creation: Is there an unresolvable circular reference?
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:327)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:217)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:891)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:834)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:749)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:558)
    ... 28 more
4

2 に答える 2

8

Springは、この種の関係を特定の順序でロードして、解決できない循環参照のように見えないようにする必要があることを理解するには、十分に賢くないと思います。通常、循環参照は、シングルトンインスタンスを作成した後、完全に入力する前にキャッシュすることで処理します。これにより、インスタンスがまだ入力されていない場合でも、後で設定が完了することがわかっているため、必要な場所にインスタンスを挿入できます。

何が起こっているのかというと、最初にAを作成しようとしているのですが、Bなしでは作成できないため、Aインスタンスをキャッシュできません。次に、Bを作成しようとし、Aが必要であることを確認しますが、Aを作成中であることはわかっていますが、依存関係に使用するキャッシュインスタンスがないため、失敗します。最初に。のようなものでBインスタンスを作成するように強制する必要があります@DependsOn("dependencyTest.B")。次に、Aを必要とせずにBを構築できるため、シングルトンキャッシングを実行できます。したがって、Aを作成するときに、入力されていないBインスタンスを使用できます。

于 2013-03-04T05:10:39.800 に答える
2

Beanは最初にインスタンス化され、次に相互に注入されます。それがあなたがこの状況に直面している理由です。インスタンス化される場合A、が必要Bです。

インスタンス化フェーズは依存関係を追加せずに実行されるため、コンストラクターの代わりにセッターを使用すると、この問題が解決されます。

于 2013-03-04T05:22:09.283 に答える