Spring Setter Dependency Injection Example
Learn how to write Spring Setter Dependency Injection Example. The Setter Injection is a type of Spring Dependency Injection. Spring supports Field Injection, Setter Injection as well as Constructor injection to inject dependencies in a Spring managed bean. Scope of this tutorial is limited to Setter Injections.
More on Spring Dependency Injection:
- Spring Constructor Dependency Injection Example
- Spring Field Dependency Injection Example
- Spring Dependency Injection – Field vs Setter vs Constructor Injection
- Spring Dependency Injection and Inversion of Control
Consider, we have a DogsService, which is a Spring based REST Service.
We will write a DogsController
, DogsService
, and a DogsDao
. This is a dummy service which does nothing. Intention here is to see how the Spring Dependency Injection works with Setter methods.
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 Dependency Injection and Inversion of Control
- Spring Boot Rest Service
DogsDao.java
There are no fields hence no dependency. We have added a no-argument constructor with a print message.
package com.amitph.spring.dogs.dao; 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; } }
DogsService.java
The DogsService
depends on DogsDao
. In the class below the setter method is annotated with @Autowired
. To see how the Setter Injection works we have added a print statement in the setter method. Along with a setter method, we have also added a no-argument constructor and a parameterised constructor with respective print messages.
package com.amitph.spring.dogs.service; 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(); } @Autowired public void setDao(DogsDao dao) { System.out.println("DogsService setter called"); this.dao = dao; } public DogsService(){ System.out.println("DogsService no-arg constructor called"); } public DogsService(DogsDao dao) { System.out.println("DogsService arg constructor called"); this.dao = dao; } }
DogsController.java
The DogsController
depends upon DogsService
. The setter is annotated with @Autowired
and has a print statement. Along with the setter method, we have also added a no-argument and a parameterised constructor along with respective print messages.
package com.amitph.spring.dogs.web; 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(); } @Autowired public void setService(DogsService service) { System.out.println("DogsController setter called"); this.service = service; } }
Application Startup
. ____ _ __ _ _ /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \ \\/ ___)| |_)| | | | | || (_| | ) ) ) ) ' |____| .__|_| |_|_| |_\__, | / / / / =========|_|==============|___/=/_/_/_/ :: Spring Boot :: (v2.1.0.RELEASE) 2019-02-04 19:06:17.058 INFO 68545 --- [ main] com.amitph.spring.dogs.Application : Starting Application on Amitsofficemac.gateway with PID 68545 (/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:06:17.061 INFO 68545 --- [ main] com.amitph.spring.dogs.Application : No active profile set, falling back to default profiles: default 2019-02-04 19:06:17.670 INFO 68545 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data repositories in DEFAULT mode. 2019-02-04 19:06:17.724 INFO 68545 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 48ms. Found 1 repository interfaces. 2019-02-04 19:06:17.992 INFO 68545 --- [ main] trationDelegate$BeanPostProcessorChecker : Bean 'org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration' of type [org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration$$EnhancerBySpringCGLIB$$4a5366ed] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying) 2019-02-04 19:06:18.225 INFO 68545 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http) 2019-02-04 19:06:18.237 INFO 68545 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat] 2019-02-04 19:06:18.237 INFO 68545 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/9.0.12 2019-02-04 19:06:18.242 INFO 68545 --- [ 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:06:18.315 INFO 68545 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2019-02-04 19:06:18.315 INFO 68545 --- [ main] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1205 ms 2019-02-04 19:06:18.339 INFO 68545 --- [ main] o.s.b.w.servlet.ServletRegistrationBean : Servlet dispatcherServlet mapped to [/] 2019-02-04 19:06:18.342 INFO 68545 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*] 2019-02-04 19:06:18.342 INFO 68545 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*] 2019-02-04 19:06:18.342 INFO 68545 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'formContentFilter' to: [/*] 2019-02-04 19:06:18.342 INFO 68545 --- [ main] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*] 2019-02-04 19:06:18.434 INFO 68545 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2019-02-04 19:06:18.524 INFO 68545 --- [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2019-02-04 19:06:18.645 INFO 68545 --- [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [ name: default ...] 2019-02-04 19:06:18.690 INFO 68545 --- [ main] org.hibernate.Version : HHH000412: Hibernate Core {5.3.7.Final} 2019-02-04 19:06:18.691 INFO 68545 --- [ main] org.hibernate.cfg.Environment : HHH000206: hibernate.properties not found 2019-02-04 19:06:18.779 INFO 68545 --- [ main] o.hibernate.annotations.common.Version : HCANN000001: Hibernate Commons Annotations {5.0.4.Final} 2019-02-04 19:06:18.868 INFO 68545 --- [ main] org.hibernate.dialect.Dialect : HHH000400: Using dialect: org.hibernate.dialect.MySQL5InnoDBDialect 2019-02-04 19:06:19.279 INFO 68545 --- [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' DogsDao no-arg constructor called DogsService no-arg constructor called DogsService setter called DogsController no-arg constructor called DogsController setter called 2019-02-04 19:06:19.650 INFO 68545 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor' 2019-02-04 19:06:19.681 WARN 68545 --- [ 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:06:19.856 INFO 68545 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path '' 2019-02-04 19:06:19.859 INFO 68545 --- [ main] com.amitph.spring.dogs.Application : Started Application in 3.138 seconds (JVM running for 3.647)
What happened here is the Spring first tried to instantiate DogsController
and found a dependency over DogsService
. Hence, it went to instantiate DogsService
, which in-turn has a dependency over DogsDao
. Hence the DogsDao
is the first to get instantiated, then DogsService
and finally the DogsController
.
Let’s see what happened in detail.
- Line #36: No-argument constructor of
DogsDao
is called. - Line #37: No-argument constructor of
DogsService
is called. Note: the parameterised constructor never got called. - Line #38: Setter of
DogsService
is called. Where instance ofDogsDao
(created at line #36) is injected. - Line #39: No-argument constructor of
DogsController
is called. - Line #40: Setter of
DogsController
is called. TheDogsService
instance (created in line #37) is injected.
Summary
You learnt How to write a Setter Injection in a Spring Application. In case of Setter Injection, the setter methods are annotated with @Autowired
. Spring will first use the no-argument constructor to instantiate the bean and then call setter methods to inject the dependencies.
In the coming tutorial we will see how the Constructor Based Injection works.
Published on Java Code Geeks with permission by Amit Phaltankar, partner at our JCG program. See the original article here: Spring Setter Dependency Injection Example Opinions expressed by Java Code Geeks contributors are their own. |