Spring Beans Autowiring
In spring framework, setting bean dependencies in configuration files is a good practice to follow, but the spring container is also able to autowire relationships between collaborating beans. This means that it is possible to automatically let Spring resolve collaborators (other beans) for your bean by inspecting the contents of the BeanFactory. Autowiring is specified per bean and can thus be enabled for some beans, while other beans will not be autowired.
Spring autowiring modes
The autowiring functionality has five modes. These are ‘no’, ‘byName’, ‘byType’, ‘constructor’, and ‘autodetect’. The default mode is “no” i.e. by default autowiring is turned off.
Sections in this post: Various autowiring modes used in bean configuration file Using autowiring with @Autowired annotations Using @Qualifier in case of conflict Making autowiring error safe using required=false Excluding a bean from being available for autowiring
Various autowiring modes used in bean configuration file
As shown in picture above, there are five auto wiring modes. Lets discuss them one by one.
- no: This option is default for spring framework and it means that autowiring is OFF. You have to explicitly set the dependencies using <property> tags in bean definitions.
- byName: This option enables the dependency injection based on bean names. When autowiring a property in bean, property name is used for searching a matching bean definition in configuration file. If such bean is found, it is injected in property. If no such bean is found, a error is raised.
- byType: This option enables the dependency injection based on bean types. When autowiring a property in bean, property’s class type is used for searching a matching bean definition in configuration file. If such bean is found, it is injected in property. If no such bean is found, a error is raised.
- constructor: Autowiring by constructor is similar to byType, but applies to constructor arguments. In autowire enabled bean, it will look for class type of constructor arguments, and then do a autowire by type on all constructor arguments. Please note that if there isn’t exactly one bean of the constructor argument type in the container, a fatal error is raised.
Autowire by constructor example
- autodetect: Autowiring by autodetect uses either of two modes i.e. constructor or byType modes. First it will try to look for valid constructor with arguments, If found the constructor mode is chosen. If there is no constructor defined in bean, or explicit default no-args constructor is present, the autowire byType mode is chosen.
Autowire by autodetect example
Using autowiring with @Autowired annotations
Apart from the autowiring modes provided in bean configuration file, autowiring can be specified in bean classes also using @Autowired annotation. To use @Autowired annotation in bean classes, you must first enable the annotation in spring application using below configuration.
|
Same can be acheived using ‘AutowiredAnnotationBeanPostProcessor’ bean definition in configuration file.
|
Now, when annotation configuration has been enables, you are free to autowire bean dependencies using @Autowired
, the way you like. This is done by three ways:
1) @Autowired on properties
When @Autowired
is used on properties, it is equivalent to autowiring by ‘byType‘ in configuration file.
|
2) @Autowired on property setters
When @Autowired is used on setters, it is also equivalent to autowiring by ‘byType’ in configuration file.
|
3) @Autowired on constructors
When @Autowired is used on bean’s constructor, it is also equivalent to autowiring by ‘constructor’ in configuration file.
|
Using @Qualifier in case of conflict
As we learned that if we are using autowiring in ‘byType‘ mode and dependencies are looked for property class types. If no such type is found, an error is thrown. But, what if there are two or more beans for same class type.
In this case spring will not be able to choose correct bean to inject into property, and you will need to help the container using qualifiers.
To resolve a specific bean using qualifier, we need to use @Qualifier
annotation along with @Autowired
annotation and pass the bean name in annotation parameter. Take a look below for example:
|
where duplicate beans are as below:
|
Making autowiring error safe using required=false
Even if you have used utmost care in autowiring bean dependencies, still you may find strange lookup failures. So, solve this issue, you will need to make autowiring optional so that if no dependency is found, application should not throw any exception and autowiring should simpy be ignored.
This can be done in two ways:
1)If you want to make specific bean autowiring non-mandatory for a specific bean property, use required=”false”attribute in @Autowired
annoration
|
2) If you want to apply optional autowiring at global level i.e. for all properties in all beans; use below configuration setting.
|
Excluding a bean from being available for autowiring
By default, autowiring scan and matches all bean definitions in scope. If you want to exclude some bean definitions so that they can not be injected through autowiring mode, you can do this using ‘autowire-candidate’ set to false.
1) Using ‘autowire-candidate‘ as false totally exclude a bean from being an autowire candidate. It totally exclude that specific bean definition from being available to the autowiring infrastructure.
|
2) Another option is to limit autowire candidates based on pattern-matching against bean names. The top-level <beans/> element accepts one or more patterns within its ‘default-autowire-candidates‘ attribute. For example, to limit autowire candidate status to any bean whose name ends with ‘Impl’, provide a value of ‘*Impl’. To provide multiple patterns, define them in a comma-separated list.
|
Note that an explicit value of ‘true’ or ‘false’ for a bean definition’s ‘autowire-candidate’ attribute always takes precedence, and for such beans, the pattern matching rules will not apply.
That’s all about autowiring feature available in spring framework. If you have any doubt, please drop a comment.
post a comment