A primary goal of Spring is to keep components as independent as possible, which allows these components to be reused , and also provides possibility to unit test them independently. Spring Dependency Injection principal fulfill this goal via injecting the dependency one component might need to complete its job, rather that component itself finding it’s dependency. In this post we will focus on XML based configuration.Check out Annotation example as well. Let’s get going.
- Spring Boot+AngularJS+Spring Data+Hibernate+MySQL CRUD App
- Spring Boot REST API Tutorial
- Spring Boot WAR deployment example
- Spring Boot Introduction + Hello World Example
- Secure Spring REST API using OAuth2
- AngularJS+Spring Security using Basic Authentication
- AngularJS Hello World Example
- Secure Spring REST API using Basic Authentication
- Spring 4 Caching Annotations Tutorial
- Spring 4 Cache Tutorial with EhCache
- Spring 4 MVC+JPA2+Hibernate Many-to-many Example
- Spring 4 Email Template Library Example
- Spring 4 Email With Attachment Tutorial
- Spring 4 Email Integration Tutorial
- Spring MVC 4+JMS+ActiveMQ Integration Example
- Spring 4+JMS+ActiveMQ @JmsLister @EnableJms Example
- Spring 4+JMS+ActiveMQ Integration Example
- Spring MVC 4+AngularJS Example
- Spring MVC 4+Hibernate 4 Many-to-many JSP Example
- Spring MVC 4+Hibernate 4+MySQL+Maven integration example using annotations
- Spring MVC4 FileUpload-Download Hibernate+MySQL Example
- TestNG Mockito Integration Example Stubbing Void Methods
- Maven surefire plugin and TestNG Example
- Spring MVC 4 Form Validation and Resource Handling
Spring provides mainly two ways for dependency injection
- Property Setter
- Constructor Injection
1.Using Property Setter
In this approach, dependency is injected/provided using Setter Method. Property Setter approach is more widely used in industry and simple to understand.
a) Create Sample Bean
package com.websystique.spring; import com.websystique.spring.domain.Encryption; public class Communication { private Messaging messaging; /* * DI via Setter */ public void setMessaging(Messaging messaging){ this.messaging = messaging; } public void communicate(){ messaging.sendMessage(); } }
b) Create Helper POJO interface and implementation
package com.websystique.spring.domain; public interface Messaging { public void sendMessage(); }
package com.websystique.spring.domain.impl; import com.websystique.spring.domain.Messaging; public class ActiveMQMessaging implements Messaging{ public void sendMessage() { System.out.println("Sending Message via Active MQ"); } }
c) Create Spring Configuration XML
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="activeMqMessaging" class="com.websystique.spring.domain.impl.ActiveMQMessaging" /> <bean id="communication" class="com.websystique.spring.Communication"> <property name="messaging"> <ref bean="activeMqMessaging" /> </property> </bean> </beans>
In above XML configuration, Spring will inject ‘activeMqMessaging’ bean into ‘communication’ bean using setter dependency injection. Communication’s setter method [setMessaging(Messaging messaing)] will be called to set the property.
d) create main and run application
package com.websystique.spring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppMain { public static void main(String args[]){ AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml"); Communication app = (Communication)context.getBean("communication"); app.communicate(); } }
You will see following output :
Sending Message via Active MQ
2.Using Constructor Injection
In this approach, Spring injects the required dependency via Constructor argument[s].
a) Create Sample Bean
package com.websystique.spring; import com.websystique.spring.domain.Encryption; public class Communication { private Encryption encryption; /* * DI via Constructor Injection */ public Communication(Encryption encryption){ this.encryption = encryption; } public void communicate(){ encryption.encryptData(); } }
b) Create Helper POJO interface and implementation
package com.websystique.spring.domain; public interface Encryption { public void encryptData(); }
package com.websystique.spring.domain.impl; import com.websystique.spring.domain.Encryption; public class RSAEncryption implements Encryption{ public void encryptData() { System.out.println("Encrypting data using RSA Encryption"); } }
c) Create Spring Configuration XML
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="rsaEncryption" class="com.websystique.spring.domain.impl.RSAEncryption" /> <bean id="communication" class="com.websystique.spring.Communication"> <constructor-arg> <ref bean="rsaEncryption" /> </constructor-arg> </bean> </beans>
In above XML configuration, Spring will inject ‘rsaEncryption’ bean into ‘communication’ bean using constructor dependency injection. Communication’s one arg Constructor[ Constructor(Encryption encryption)] will be called.
Remark: Although constructor injection seems simple, it can easily lead to infamous constructor ambiguities in case you have multiple constructors with same number of arguments but different types and if implicit conversion is possible between different types. It happens mostly with primitive type (int, String etc..). You can get rid of these ambiguities using ‘type’ attribute of constructor-arg element to specify exact type of argument e.g.
<bean id="communication" class="com.websystique.spring.Communication"> <constructor-arg type="com.websystique.spring.domain.Encryption"> <ref bean="rsaEncryption" /> </constructor-arg> </bean>
d) create main and run application
package com.websystique.spring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppMain { public static void main(String args[]){ AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml"); Communication app = (Communication)context.getBean("communication"); app.communicate(); } }
You will see following output :
Encrypting data using RSA Encryption
Using both approach together on same Bean
It is also possible to use them together in same bean, although on different items.
Bean Class
package com.websystique.spring; import com.websystique.spring.domain.Encryption; import com.websystique.spring.domain.Messaging; public class Communication { private Messaging messaging; private Encryption encryption; /* * DI via Constructor Injection */ public Communication(Encryption encryption){ this.encryption = encryption; } /* * DI via Setter */ public void setMessaging(Messaging messaging){ this.messaging = messaging; } public void communicate(){ encryption.encryptData(); messaging.sendMessage(); } }
Spring Configuration Class
package com.websystique.spring.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Description; import com.websystique.spring.Communication; import com.websystique.spring.domain.Encryption; import com.websystique.spring.domain.Messaging; import com.websystique.spring.domain.impl.ActiveMQMessaging; import com.websystique.spring.domain.impl.RSAEncryption; @Configuration public class AppConfig { @Bean(name = "communication") public Communication communication() { Communication communication = new Communication(encryption()); communication.setMessaging(messaging()); return communication; } @Bean(name = "encryption") @Description("This bean will be injected via setter injection") public Encryption encryption() { return new RSAEncryption(); } @Bean(name = "messaging") @Description("This bean will be injected via setter injection") public Messaging messaging() { return new ActiveMQMessaging(); } }
Spring XML configuration
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <bean id="activeMqMessaging" class="com.websystique.spring.domain.impl.ActiveMQMessaging" /> <bean id="rsaEncryption" class="com.websystique.spring.domain.impl.RSAEncryption" /> <bean id="communication" class="com.websystique.spring.Communication"> <constructor-arg> <ref bean="rsaEncryption" /> </constructor-arg> <property name="messaging"> <ref bean="activeMqMessaging" /> </property> </bean> </beans>
In above configuration, we are using Property Setter approach to inject ‘activeMqMessaging’ bean into ‘messaging’ property. On the other hand, we are using Constructor Injection approach to inject ‘rsaEncryption’ bean into Communication constructor.
Run Main
package com.websystique.spring; import org.springframework.context.support.AbstractApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class AppMain { public static void main(String args[]){ AbstractApplicationContext context = new ClassPathXmlApplicationContext("app-config.xml"); Communication app = (Communication)context.getBean("communication"); app.communicate(); } }
You will see following output :
Encrypting data using RSA Encryption Sending Message via Active MQ
That’s it.
Below is the Directory Structure for this post:
And referenced pom.xml for this project is:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.websystique.spring</groupId> <artifactId>SpringDIWithXMLExample</artifactId> <version>1.0.0</version> <packaging>jar</packaging> <name>SpringDIWithXMLExample</name> <properties> <springframework.version>4.0.6.RELEASE</springframework.version> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${springframework.version}</version> </dependency> </dependencies> </project>
Download Source Code
References
If you like tutorials on this site, why not take a step further and connect me on Facebook , Google Plus & Twitter as well? I would love to hear your thoughts on these articles, it will help improve further our learning process.