Spring Constructor Dependency Injection Example
Welcome to Spring Constructor Dependency Injection Example guide. The Constructor based Dependency Injection is a type of Spring Dependency Injection. The other type of dependency injections are Setter Injection & Field Injection.
More on Spring Dependency Injection:
- Example of Setter Injection in Spring
- Field Injection in Spring
- Dependency Injection – Constructor vs field injection
- Dependency Injection and Inversion of Control
Constructor Based Dependency Injection
It is a type of Spring Dependency Injection, where object’s constructor is used to inject dependencies. This type of injection is safer as the objects won’t get created if the dependencies aren’t available or dependencies cannot be resolved.
To understand, how the Constructor based Dependency Injection works in Spring – obviously – we need a Spring Application. Consider we have very simple Spring Application called as DogsService, which is a dummy service.
Don’t know how to write Spring Boot Rest Service?
Read this: Spring Boot Rest Service
Want to learn more about Spring Framework ?
Read this:
- Introduction to Spring Framework
- Spring Framework Architecture
- Spring Beans – Singleton Vs Prototype
- Autowiring in Spring
The Dogs DAO
The DAO class doesn’t have any dependency. We have added a no-argument constructor with print statement.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | import com.amitph.spring.dogs.repo.Dog; import org.springframework.stereotype.Component; import java.util.List; @Component public class DogsDao { public DogsDao(){ System.out.println( "DogsDao no-arg constructor called" ); } public List<Dog> getAllDogs() { System.out.println( "DogsDao.getAllDogs called" ); return null ; } } |
The Dogs Service
The Service HAS-A DogsDao
. The service class has a setter method, a no-argument constructor, and a parameterised constructor with respective print statements.
Note: The parameterised constructor is annotated with @Autowrired
.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import com.amitph.spring.dogs.dao.DogsDao; import com.amitph.spring.dogs.repo.Dog; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.List; @Component public class DogsService { private DogsDao dao; public List<Dog> getDogs() { System.out.println( "DogsService.getDogs called" ); return dao.getAllDogs(); } public void setDao(DogsDao dao) { System.out.println( "DogsService setter called" ); this .dao = dao; } public DogsService(){ System.out.println( "DogsService no-arg constructor called" ); } @Autowired public DogsService(DogsDao dao) { System.out.println( "DogsService arg constructor called" ); this .dao = dao; } } |
The Dogs Controller
The Controller HAS-A DogsService
. The controller class also has one setter, a no-argument constructor and a parameterised constructor with respective print statements.
Note: The parameterised constructor is annotated with @Autowrired
.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | import com.amitph.spring.dogs.repo.Dog; import com.amitph.spring.dogs.service.DogsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping ( "/dogs" ) public class DogsController { private DogsService service; @GetMapping public List<Dog> getDogs() { return service.getDogs(); } public void setService(DogsService service) { System.out.println( "DogsController setter called" ); this .service = service; } public DogsController(){ System.out.println( "DogsController no-arg constructor called" ); } @Autowired public DogsController(DogsService service) { System.out.println( "DogsController arg constructor called" ); this .service = service; } } |
Run The Application
When we start the application, we should see below logs on the console.
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | 2019 - 02 - 04 19 : 56 : 46.812 INFO 68906 --- [ main] com.amitph.spring.dogs.Application : Starting Application on Amitsofficemac.gateway with PID 68906 (/Users/aphaltankar/Workspace/personal/dog-service-jpa/out/production/classes started by aphaltankar in /Users/aphaltankar/Workspace/personal/dog-service-jpa) 2019 - 02 - 04 19 : 56 : 46.815 INFO 68906 --- [ main] com.amitph.spring.dogs.Application : No active profile set, falling back to default profiles: default 2019 - 02 - 04 19 : 56 : 47.379 INFO 68906 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode. 2019 - 02 - 04 19 : 56 : 47.428 INFO 68906 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 45ms. Found 1 repository interfaces. 2019 - 02 - 04 19 : 56 : 47.682 INFO 68906 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$EnhancerBySpringCGLIB$86296a04] is not eligible for getting processed by all BeanPostProcessors ( for example: not eligible for auto-proxying) 2019 - 02 - 04 19 : 56 : 47.931 INFO 68906 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019 - 02 - 04 19 : 56 : 47.944 INFO 68906 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019 - 02 - 04 19 : 56 : 47.944 INFO 68906 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/ 9.0 . 12 2019 - 02 - 04 19 : 56 : 47.949 INFO 68906 --- [ main] o.a.catalina.core.AprLifecycleListener : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [/Users/aphaltankar/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.] 2019 - 02 - 04 19 : 56 : 48.021 INFO 68906 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019 - 02 - 04 19 : 56 : 48.021 INFO 68906 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1158 ms 2019 - 02 - 04 19 : 56 : 48.042 INFO 68906 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2019 - 02 - 04 19 : 56 : 48.045 INFO 68906 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2019 - 02 - 04 19 : 56 : 48.046 INFO 68906 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2019 - 02 - 04 19 : 56 : 48.046 INFO 68906 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'formContentFilter' to: [/*] 2019 - 02 - 04 19 : 56 : 48.046 INFO 68906 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2019 - 02 - 04 19 : 56 : 48.136 INFO 68906 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool- 1 - Starting... 2019 - 02 - 04 19 : 56 : 48.230 INFO 68906 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool- 1 - Start completed. 2019 - 02 - 04 19 : 56 : 48.322 INFO 68906 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [ name: default ...] 2019 - 02 - 04 19 : 56 : 48.366 INFO 68906 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core { 5.3 . 7 .Final} 2019 - 02 - 04 19 : 56 : 48.366 INFO 68906 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found 2019 - 02 - 04 19 : 56 : 48.461 INFO 68906 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations { 5.0 . 4 .Final} 2019 - 02 - 04 19 : 56 : 48.546 INFO 68906 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect 2019 - 02 - 04 19 : 56 : 48.960 INFO 68906 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' DogsDao no-arg constructor called DogsService arg constructor called DogsController arg constructor called 2019 - 02 - 04 19 : 56 : 49.304 INFO 68906 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019 - 02 - 04 19 : 56 : 49.330 WARN 68906 --- [ main] aWebConfiguration$JpaWebMvcConfiguration : spring.jpa.open-in-view is enabled by default . Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning 2019 - 02 - 04 19 : 56 : 49.479 INFO 68906 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019 - 02 - 04 19 : 56 : 49.482 INFO 68906 --- [ main] com.amitph.spring.dogs.Application : Started Application in 3.003 seconds (JVM running for 3.521 ) |
- Line #27: As expected, the no-argument constructor of DAO is called.
- Line #28: A parameterised constructor of
DogsService
is called along with an instance of DAO created at line #27. - Line #29: A parameterised constructor of the controller is called along with a service instance created at line #28.
Notice here that neither the setters nor the no-argument constructors were invoked by Spring. The dependencies were injected purely by means of Constructors. This approach is preferred over Spring Setter Injection and Field Injection in Spring.
Summary
In this Spring Constructor Dependency Injection Example guide, you learnt how Constructor based Dependency Injection works in a Spring Application. We also wrote executable code with Constructor Injection.
When constructor is used to set instance variables on an objects, it is called as Constructor Injection. Before you dig deeper into using Spring Framework it is important to understand Difference Between Setter Injection Vs Field Injection Vs Constructor Injection.
Happy Coding !!
Published on Java Code Geeks with permission by Amit Phaltankar, partner at our JCG program. See the original article here: Spring Constructor Dependency Injection Example Opinions expressed by Java Code Geeks contributors are their own. |