Spring: Static Bean Declared Inside Another Bean Is Not Initialized on Java Config

advertisements

I have a simple Spring boot application with following classes:

Class A, it has the Class B declared as a bean with a static method:

public class ClassA {
    private String something;

    public ClassA(String something) {
        this.something = something;
    }

    @PostConstruct
    protected void postConstruct() {
        System.out.println("Class A initialized! " + something);
    }

    @Bean
    public static ClassB classB() {
        return new ClassB();
    }
}

Class B:

public class ClassB {
    @PostConstruct
    protected void postConstruct() {
        System.out.println("Class B initialized!");
    }
}

and the entry point of my Spring Boot application class:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

My problem is, I want to get both ClassA and ClassB beans created, by only defining ClassA explicitly as bean. If I do this with an XML configuration such as:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.mypackage.ClassA">
        <constructor-arg name="something" value="Hello from XML Config!"/>
    </bean>
</beans>

and import it on Application class using @ImportResource("classpath:applicationContext.xml") Spring creates class A and processes @Bean annotation on class A and creates an instance of class B. Program output is:

Class A initialized! Hello from XML Config!
Class B initialized!

But when I try to do the same thing using Java configuration, defining bean of A in Application class as follows:

@Bean
public ClassA classA() {
    return new ClassA("Hello from Java Config!");
}

Then an instance of B does not get created, so the program output is:

Class A initialized! Hello from Java Config!

My question is, how can I get the same behavior of XML configuration with Java configuration.

Note: I tried @Import(ClassA.class) on application configuration but it failed after creating the bean of B because it tried to create an instance but A does not have a default constructor.


An option is aggregate:

 @Bean
 public ClassB classB() {
    return ClassA.classB();
 }

At the end of your Application class.

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

    @Bean
    public ClassA classA() {
        return new ClassA("Hello from Java Config!");
    }

    @Bean
    public ClassB classB() {
        return ClassA.classB();
    }
}

The result is:

Class A initialized! Hello from Java Config!
Class B initialized!