user2184293
user2184293

Reputation: 51

Reference a bean as part of a constructor to a different bean in java config

I am having trouble converting bean references in xml to java config. In the XML I have something similar to this:

<bean id="user" com="User">
    <constructor-arg name="pFirst" value="first" />
    <constructor-arg name="pSecond" value="second" />
    <constructor-arg name="pThird" value="third" />
</bean>

<bean id="department" com="Department">
    <constructor-arg name="pfourth" value="fourth" />
    <constructor-arg name="pFifth" value="fifth" />
    <constructor-arg ref="user" />
</bean>

In the java config I now have this:

@Bean
@Autowired
public User user(First first, Second second, Third third)
{
    return new User(first, second, third);
}

@Bean
@Autowired
public Department department(First first, Second second, Third third, Fourth fourth, Fifth fifth)
{
    return new Department(fourth, fifth, user(first, second, third));
}

I do not want to have to pass the same parameters to the department as I do to the user. In XML I could reference the user bean and use it without the other parameters. How can I do this in the java config file. I would like the java config file to look something like the following:

@Bean
@Autowired
public User user(First first, Second second, Third third)
{
    return new User(first, second, third);
}

@Bean
@Autowired
public Department department(Fourth fourth, Fifth fifth, User user)
{
    return new Department(fourth, fifth, user);
}

This one uses the previously defined bean as the third parameter, but I can't get anything like this to work.

How would I reference the User bean as part of a constructor to another bean?

Upvotes: 0

Views: 3033

Answers (2)

Mekswoll
Mekswoll

Reputation: 1433

@Bean
public User user() {
    return new User("first", "second", "third");
}

@Bean
public Department department() {
    return new Department("fourth", "fifth", user());
}

Now you can user @Autowired in other classes that are in the container and inject your user or department (e.g. in a controller)

@Autowired
private User user; // will return the user from the user() java config defined bean

Upvotes: 2

First, @Bean methods generally shouldn't be annotated @Autowired; that should be applied to fields on the @Configuration object containing the beans.

@Configuration
public class MyConfig {
    @Autowired First first;
    @Autowired Second second;
    @Autowired Third third;

    @Bean public User user() {
        return new User(first, second, third);
    }

    @Autowired Fourth fourth;
    @Autowired Fifth fifth;

    @Bean public Department department() {
        // call to user() is magically proxied to apply Spring bean scope
        return new Department(fourth, fifth, user());
    }
}

This is usually sufficient for Spring to handle the appropriate dependencies. In the odd cases where there's ambiguity or other difficulty, you can use a nested configuration class:

@Configuration
public class MyConfig {
    @Autowired First first;
    @Autowired Second second;
    @Autowired Third third;

    @Bean public User user() {
        return new User(first, second, third);
    }

    @Configuration
    public static class MySubConfig {
        @Autowired Fourth fourth;
        @Autowired Fifth fifth;
        @Autowired User user;

        @Bean public Department department() {
            return new Department(fourth, fifth, user);
        }
    }
}

Upvotes: 0

Related Questions