3

コンパイル時のウィービングを介して AspectJ で Spring を使用して、コンテナーによって管理されていないオブジェクトに @Configurable スプリング アノテーションを使用しています。

@Configurable-annotated オブジェクトの例を次に示します。

@Configurable(autowire = Autowire.BY_TYPE)
public class TestConfigurable {

    private TestComponent component;

    public TestComponent getComponent() {
        return component;
    }

    @Autowired
    public void setComponent(TestComponent component) {
        this.component = component;
    }
}

このオブジェクトに注入するコンポーネント:

@Component
public class TestComponent {}

コンテキストが作成された後に TestConfigurable を作成すると、そこに TestComponent が正常に注入されますが、 @PostConstruct-annotated メソッドからそうしている場合、自動配線は行われません。

@PostConstruct を持つコンポーネント:

@Component
public class TestPostConstruct {

    @PostConstruct
    public void initialize() {
        TestConfigurable configurable = new TestConfigurable();
        System.out.println("In post construct: " + configurable.getComponent());
    }
}

私が実行しているアプリケーション:

public class TestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext applicationContext = new ClassPathXmlApplicationContext("/application-context.xml");
        applicationContext.registerShutdownHook();

        TestConfigurable configurable = new TestConfigurable();
        System.out.println("After context is loaded: " + configurable.getComponent());
    }
}

このアプリケーションが生成する出力は次のとおりです。

In post construct: null
After context is loaded: paulenka.aleh.roguelike.sandbox.TestComponent@fe18270

@PostConstruct メソッド内で作成された @Configurable オブジェクトに依存関係を注入する回避策はありますか? @Component アノテーションが付けられたすべての Bean はすでにコンテキスト内にあり、@PostConstruct が呼び出された時点でそれらの自動配線がすでに行われています。ここで Spring が自動配線を行わないのはなぜですか? ...

問題の解決に役立つ場合は、他の構成ファイル (context および pom.xml) を投稿できます。

更新 1: 問題の原因が見つかったようです。@Configurable でアノテーションが付けられたオブジェクトは、BeanFactoryAware を実装する AnnotationBeanConfigurerAspect によって初期化されます。このアスペクトは、BeanFactory を使用して Bean を初期化します。BeanFactory が AnnotationBeanConfigurerAspect に設定される前に、TestPostConstruct オブジェクトの @PostConstruct メソッドが実行されているようです。ロガーがデバッグに設定されている場合、次のメッセージがコンソールに出力されます。 "

回避策があるかどうかという質問は、まだ私にとって未解決です...

4

2 に答える 2

5

これに対する1つの回避策を見つけました。@PostConstruct が実行される前に AnnotationBeanConfigurerAspect アスペクトを初期化するには、そのような @PostConstruct メソッドを使用してクラスに次のアノテーションを追加できます。

@DependsOn("org.springframework.context.config.internalBeanConfigurerAspect")

この情報が誰かにとって役立つことを願っています。

于 2014-12-02T08:21:08.353 に答える