简体   繁体   中英

Spring beans initialization through method

I have a little question about bean creation that bothers me a lot.

For example I have classes

public class A {
    B b;
    public A(B b) { 
        this.b = b;
    }
}
public class B {}

And I want to make beans for them like this:

@Configuration 
public class Config {

@Bean
public B beanB() {
    return new B();
}
//version 1
@Bean
public A beanA() {
    return new A(beanB())
}
//version 2
@Bean
public A beanA(B beanB) {
    return new A(beanB)
}
}

So, my question is what is the right way to create bean A?

I think that the right one is version 2, because in the version 1 I think beanB can be invoked 2 times: on the creation of beanA and when spring will create it for it's context. But I can't find anything that will prove my opinion.

The "right" way is to do it the way the documentation , ie the javadoc of @Bean , shows it:

@Bean Methods in @Configuration Classes

Typically, @Bean methods are declared within @Configuration classes. In this case, bean methods may reference other @Bean methods in the same class by calling them directly . This ensures that references between beans are strongly typed and navigable. Such so-called 'inter-bean references' are guaranteed to respect scoping and AOP semantics, just like getBean() lookups would. These are the semantics known from the original 'Spring JavaConfig' project which require CGLIB subclassing of each such configuration class at runtime. As a consequence, @Configuration classes and their factory methods must not be marked as final or private in this mode. For example:

 @Configuration public class AppConfig { @Bean public FooService fooService() { return new FooService(fooRepository()); } @Bean public FooRepository fooRepository() { return new JdbcFooRepository(dataSource()); } //... }

That means version 1 in the question code.

Spring dynamically subclasses AppConfig , so only one instance is created no matter how many times the method is called, eg functionally something like this:

public class $dynamic$ extends AppConfig {
    private FooRepository cachedFooRepository;

    @Override
    public FooRepository fooRepository() {
        if (this.cachedFooRepository == null)
            this.cachedFooRepository = super.fooRepository();
        return cachedFooRepository;
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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