Autowiring in Spring

Setting bean dependencies in the configuration file is a good practice to follow in the Spring Framework; however, the Spring container can automatically autowire relationships between collaborating beans by inspecting the contents of BeanFactory.

As we have seen, every member variable in the Spring bean has to be configured; for example, if a bean references another bean, we have to specify the reference explicitly. Autowiring is a feature provided by the Spring Framework that helps us reduce some of these configurations by intelligently guessing what the reference is.

The Spring Framework provides autowiring features where we don't need to provide bean injection details explicitly. The Spring container can autowire relationships between collaborating beans without using the <constructor-arg> and <property> elements. This immensely helps in cutting down the XML configuration. Spring is capable of automatically resolving dependencies at runtime. This automatic resolution of bean dependencies is also called autowiring.

Spring wires a bean's properties automatically by setting the autowire property on each <bean> tag that you want to autowire. By default, autowiring is disabled. To enable it, specify the method of autowiring you want to apply using the autowire attribute of the bean you want to autowire, as shown here:

<bean id="foo" class ="Foo" autowire="autowire-type" />

Autowiring modes

There are five modes of autowiring that Spring Container can use for autowiring. They are explained in the following table:

Mode

Description

No

By default, Spring bean autowiring is turned off, that is, no autowiring is to be performed, and you should use explicit bean reference ref for wiring.

byname

This is autowiring by property name, that is, if the bean property is the same as the other bean name, autowire it. The setter method is used for this type of autowiring to inject a dependency.

byType

The data type is used for this type of autowiring. If the data type bean property is compatible with the data type of the other bean, autowire it. Only one bean should be configured for this type in the configuration file; otherwise, a fatal exception is thrown.

constructor

This is similar to autowire byType, but here the constructor is used to inject a dependency.

autodetect

Spring first tries to autowire by the constructor; if it does not work, then Spring tries to autowire with byType. This option is deprecated.

Let's demonstrate autowiring with examples.

In the EmployeeServiceImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.autowiring;

public class EmployeeServiceImpl implements EmployeeService {

   private EmployeeDao employeeDao = null;

   public void setEmployeeDao(EmployeeDao employeeDao) {
          this.employeeDao = employeeDao;
   }
}

In the EmployeeDaoImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.autowiring;

public class EmployeeDaoImpl implements EmployeeDao {

   // ...

}

In the preceding code snippet, the EmployeeServiceImpl class has employeeDaofield and a setter method.

Autowiring using the no option

This is a default mode, and you should use the explicit bean reference ref for wiring.

In the beans.xml file, you'll find the following code:

...
   <bean id="employeeService"
   class="org.packt.Spring.chapter2.autowiring.EmployeeServiceImpl">
          <property name="employeeDao" ref="employeeDaoBean"></property>
   </bean>

   <bean id="employeeDaoBean" class="org.packt.Spring.chapter2.autowiring.EmployeeDaoImpl">
   </bean>
...

Autowiring using the byname option

Autowiring using the byName option autowires a bean by its property name.

A Spring container looks at the properties of the beans on which the autowire attribute is set using byName in the configuration file. It then tries to match and wire its properties with the beans defined by the same names in the configuration file. If such a bean is found, it is injected into the property. If no such bean is found, an error is raised.

Case 1 – if id=" employeeDao"

In the beans.xml file, you'll find the following code:

...
   <bean id="employeeService"
   class="org.packt.Spring.chapter2.autowiring.EmployeeServiceImpl"
         autowire="byName">
   </bean>

   <bean id="employeeDao" class="org.packt.Spring.chapter2.autowiring.EmployeeDaoImpl">
   </bean>

...

In this case, since the name of the employeeDao bean is the same as the employeeService bean's property (EmployeeDao employeeDao), Spring will autowire it via the setter method setEmployeeDao (EmployeeDao employeeDao).

Case 2 – if id=" employeeDaoBean"

In the beans.xml file, you'll find the following code:

...
   <bean id="employeeService"
   class="org.packt.Spring.chapter2.autowiring.EmployeeServiceImpl"
          autowire="byName">
   </bean>

   <bean id="employeeDaoBean" class="org.packt.Spring.chapter2.autowiring.EmployeeDaoImpl">
   </bean>

...

In this case, since the name of the employeeDaoBean bean is not the same as the employeeService bean's property (EmployeeDao employeeDao), Spring will not autowire it via the setter method, setEmployeeDao(EmployeeDao employeeDao). So, the employeeDao property will get a null value.

Autowiring using the byType option

Autowiring using byType enables Dependency Injection based on property data types.

The Spring container looks at each property's class type searching for a matching bean definition in the configuration file when autowiring a property in a bean. If no such bean is found, a fatal exception is thrown. If there is more than one bean definition found in the configuration, a fatal exception is thrown, and it will not allow byType autowiring for that bean.

If there are no matching beans, nothing happens; the property is not set. So, to throw an error, use the dependency-check="objects" attribute value.

In the beans.xml file, you'll find the following code:

...
   <bean id="employeeService"
   class="org.packt.Spring.chapter2.autowiring.EmployeeServiceImpl"
         autowire="byType">
   </bean>

   <bean id="employeeDaoBean" class="org.packt.Spring.chapter2.autowiring.EmployeeDaoImpl">
   </bean>
...

In this case, since the data type of the employeeDaoBean bean is the same as the data type of the employeeService bean's property (EmployeeDao employeeDao), Spring will autowire it via the setter method setEmployeeDao(EmployeeDao employeeDao).

Autowiring using the constructor

Autowiring using the constructor applies to constructor arguments.

It will look for the class type of constructor arguments and perform autowiring using byType on all constructor arguments. A fatal error is raised if there isn't exactly one bean of the constructor argument type in the container.

In the EmployeeServiceImpl.java class, you'll find the following code:

package org.packt.Spring.chapter2.autowiring;

public class EmployeeServiceImpl implements EmployeeService {

   private EmployeeDao employeeDao;

   public EmployeeServiceImpl(EmployeeDao employeeDao) {
          this.employeeDao = employeeDao;
   }

   public EmployeeDao getEmployeeDao() {
          return employeeDao;
   }
}

In the beans.xml file, you'll find the following code:

...
   <bean id="employeeService"
   class="org.packt.Spring.chapter2.autowiring.EmployeeServiceImpl"
          autowire="constructor">
   </bean>

   <bean id="employeeDaoBean" class="org.packt.Spring.chapter2.autowiring.EmployeeDaoImpl">
   </bean>
...

In this case, since the data type of the employeeDaoBean bean is the same as the constructor argument data type in the employeeService bean's property (EmployeeDao employeeDao), Spring autowires it via the constructor: public EmployeeServiceImpl(EmployeeDao employeeDao).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.254.133