Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring autowire by name constructor arguments

We have a big java applications with thousands of beans, profiling the slow spring context initialization we found that the auto-wiring by type is what's taking most of the context loading time. Autowiring the bean by name seems to improve the context initialization by an order of magnitude. However I couldn't find a way to auto-wire beans by name as constructor arguments.

The following is a member autowire that works fine, spring does the lookup by name:

class MyClass {
   @Resource
   private MyBean mybean;
}

But since @Resource only applies to members and methods it doesn't apply to constructor. We tried both the @Inject with @Named and @Autowired with @Qualifier but Spring does the slow by type lookup for these approaches:

class MyClass {
   @Inject
   public MyClass(@Named("myBean") MyBean myBean) {
   }
}

class MyClass {

   @Autowired
   public MyClass(@Qualifer("myBean") MyBean myBean) {
   }
}

How to tell spring not to lookup by type when using constructor injection?

We understand the advantaged of wire by type (decouple from bean names) yet at this point context loading performance is our biggest concern.

like image 395
LiorH Avatar asked Aug 06 '14 12:08

LiorH


People also ask

Can we do @autowired by constructor?

Autowiring by constructor is enabled by using autowire="constructor" in bean definition in configuration file (i.e. application-context. xml ).

Is there a way to @autowire a bean that requires constructor arguments?

And this can be done either by using the @Autowired annotation or the @Value annotation. You use the @Autowired notation when the constructor argument is another Object, while the @Value annotation comes in handy when the contructor argument can easily be evaluated using Spring expression.

Does Spring Autowired call constructor?

P.S: You can also have a constructor with parameters if you use the @Autowired annotation. On this case, Spring will call this constructor to create the bean and pass the required parameters if there are such beans declared that can be autowired into the constructor.

Can we Autowire parameterized constructor?

3) constructor autowiring modeIn case of constructor autowiring mode, spring container injects the dependency by highest parameterized constructor. If you have 3 constructors in a class, zero-arg, one-arg and two-arg then injection will be performed by calling the two-arg constructor.


1 Answers

I know it is now a bit old fashioned, but wiring by name is really easy in xml, and Spring supports mixing of xml and java configuration.

Provided bean myBean is defined in xml of java configuration, you can write

<bean id="myClass" class="...MyClass">
    <constructor-arg ref = "myBean"/>
</bean>

or in case of multiple arguments :

<bean id="myClass" class="...MyClass">
    <constructor-arg index="0" ref = "myBean"/>
    <constructor-arg index="1" ref = "myOtherBean"/>
</bean>

EDIT

Alternatively in a java config way you can have :

@Configuration
public class MyClassConfig() {

@Autowire
@Qualifier("myBean")
MyBean myBean;

@Bean
MyClass myclass = new MyClass(myBean);
}

Thanks to jny for suggesting it.

like image 184
Serge Ballesta Avatar answered Oct 17 '22 19:10

Serge Ballesta