DEPENDENCY INJECTION EXAMPLE USING SPRING

Dependency Injection

The Spring Framework is literally built around the concept of Dependency Injection. In this post, we’ll take a look at a simple example of Dependency Injection using the Spring Framework.

If you want a deeper dive on Dependency Injection and how it works in conjunction with Inversion of Control in the Spring Framework, sign up for my free Introduction to Spring tutorial at the bottom of this post.

Dependency Injection Example

In this blog post, I will take a realistic example of having a web controller and a service. In practice, the controller would be responsible for managing requests from the web, and the service would interact with the persistence layer.

Domain

Our service will return a domain class. In this example, our controller will return a simple list of products.

 1 package guru.springframework.domain;
 2
 3 /**
 4  * Created by jt on 3/27/15.
 5  */
 6 public class Product {
 7     private String description;
 8
 9     public Product(String description) {
10         this.description = description;
11     }
12
13     public String getDescription() {
14         return description;
15     }
16
17     public void setDescription(String description) {
18         this.description = description;
19     }
20 }

Product.class

Service Layer

Ideally, when you are coding for Dependency Injection, you will want to code to an interface. This will allow you easily utilize polymorphism and implement different concrete implementations. When coding for the use of dependency injection, coding to an interface also complies with the Interface Segregation Principle of the SOLID principles of Object Oriented Programming.

A common example would be to have the implementation you will use in your production code, and then a mock implementation for unit testing your code. This is the power of dependency injection. It allows you to change the behavior of your application through configuration changes over code changes. For example with persistence, you might be injecting a mock for unit testing, a H2 database for local development and CI builds, and then a Oracle implementation when your code is running in production. When developing enterprise class applications, dependency injection gives you a tremendous amount of versatility.

 1 package guru.springframework.services;
 2
 3 import guru.springframework.domain.Product;
 4
 5 import java.util.List;
 6
 7 /**
 8  * Created by jt on 3/27/15.
 9  */
10 public interface ProductService {
11
12     List<Product> listProducts();
13 }

ProductService.interface

Here is the implementation of the service. This is just a simple implementation which returns a list of Product domain POJOs, which is sufficient for this example. Naturally, in a real example, this implementation would be interacting with the database or possibly a web service.

I’ve annotated the class with @Service , this tells Spring this class is a Spring Bean to be managed by the Spring Framework. This step is critical, Spring will not detect this class as a Spring Bean without this annotation. Alternatively, you could explicitly define the bean in a Spring configuration file.

 1 package guru.springframework.services;
 2
 3 import guru.springframework.domain.Product;
 4 import org.springframework.stereotype.Service;
 5
 6 import java.util.ArrayList;
 7 import java.util.List;
 8
 9 /**
10  * Created by jt on 3/27/15.
11  */
12 @Service
13 public class ProductServiceImpl implements ProductService {
14
15     @Override
16     public List<Product> listProducts() {
17         ArrayList<Product> products = new ArrayList<Product>(2);
18         products.add(new Product("Product 1 description"));
19         products.add(new Product("Product 2 description"));
20         return products;
21     }
22 }

ProductServiceImpl.class

Controller

We have a simple controller to return a list of Products to our view layer. In this example, I’m using setter based Dependency Injection.   First, I’ve defined a property in our example controller using the Interface type, not the concrete class. This allows any class to be injected which implements the specified interface.  On the setter, you see the @Autowired  annotation. This directs Spring to inject a Spring managed bean into this class.  Our controller class is also annotated with the @Controller  annotation. This marks the class as a Spring Managed bean. Without this annotation, Spring will not bring this class into the context, and will not inject an instance of the service into the class.

 1 package guru.springframework.controllers;
 2
 3 import guru.springframework.domain.Product;
 4 import guru.springframework.services.ProductService;
 5 import org.springframework.beans.factory.annotation.Autowired;
 6 import org.springframework.stereotype.Controller;
 7
 8 import java.util.List;
 9
10 /**
11  * Created by jt on 3/27/15.
12  */
13 @Controller
14 public class MyController {
15
16     private ProductService productService;
17
18     @Autowired
19     public void setProductService(ProductService productService) {
20         this.productService = productService;
21     }
22
23     public List<Product> getProducts(){
24         return productService.listProducts();
25     }
26
27 }

MyController.class

Running the Example

We’ll use Spring Boot to run our example. Spring Boot will help bring up the Spring context for running our example. Spring Boot does automate a lot of common tasks for us. For example, it will automatically do a component scan in the package the class is running in.

Example Execution Code

For our example, we need to tell Spring where our components are located. We use the @ComponentScan  annotation. By using this annotation Spring will scan the specified package for Spring components (aka Spring managed beans).

In our main method, we get the Spring Context, then request from the context an instance of our controller bean. Spring will give us an instance of the controller. Spring will perform the Dependency Injection for us, and inject the dependent components into the object returned to us.

It is important to remember, the Spring Context is returning to us Spring Managed beans. This means Spring will be managing the dependency injection for us. If for some reason, Spring cannot fulfill a dependency, it will fail to startup. You will see in the stack trace information about the missing dependencies.

 1 package diexample;
 2
 3 import guru.springframework.controllers.MyController;
 4 import guru.springframework.domain.Product;
 5 import org.springframework.boot.SpringApplication;
 6 import org.springframework.boot.autoconfigure.SpringBootApplication;
 7 import org.springframework.context.ApplicationContext;
 8 import org.springframework.context.annotation.ComponentScan;
 9
10 import java.util.List;
11
12 @SpringBootApplication
13 @ComponentScan("guru.springframework")
14 public class DiExampleApplication {
15
16     public static void main(String[] args) {
17         ApplicationContext ctx = SpringApplication.run(DiExampleApplication.class, args);
18         MyController controller = (MyController) ctx.getBean("myController");
19         List<Product> products = controller.getProducts();
20
21         for(Product product : products){
22             System.out.println(product.getDescription());
23         }
24     }
25 }

DiExampleApplication.class

Console Output

When you run the above example, you will see the following output in the console.  Note in the console output, you see our two product descriptions, which proves that Spring did in fact wire our controller correctly. If Spring did not, our code would have failed on a null pointer error.

 1   .   ____          _            __ _ _
 2  /\\ / ___‘_ __ _ _(_)_ __  __ _ \ \ \  3 ( ( )\___ | ‘_ | ‘_| | ‘_ \/ _` | \ \ \  4  \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
 5   ‘  |____| .__|_| |_|_| |_\__, | / / / /
 6  =========|_|==============|___/=/_/_/_/
 7  :: Spring Boot ::        (v1.2.2.RELEASE)
 8
 9 2015-03-27 10:28:21.016  INFO 64108 --- [           main] diexample.DiExampleApplication           : Starting DiExampleApplication on Johns-MacBook-Pro.local with PID 64108 (/Users/jt/src/springframework.guru/blog/di-example/target/classes started by jt in /Users/jt/src/springframework.guru/blog/di-example)
10 2015-03-27 10:28:21.115  INFO 64108 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]3e57cd70: startup date [Fri Mar 27 10:28:21 EDT 2015]; root of context hierarchy
11 2015-03-27 10:28:22.107  INFO 64108 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
12 2015-03-27 10:28:22.121  INFO 64108 --- [           main] diexample.DiExampleApplication           : Started DiExampleApplication in 1.606 seconds (JVM running for 2.134)
13 Product 1 description
14 Product 2 description
15 2015-03-27 10:28:22.122  INFO 64108 --- [       Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.spring[email protected]3e57cd70: startup date [Fri Mar 27 10:28:21 EDT 2015]; root of context hierarchy
16 2015-03-27 10:28:22.123  INFO 64108 --- [       Thread-1] o.s.j.e.a.AnnotationMBeanExporter        : Unregistering JMX-exposed beans on shutdown

Output

时间: 2024-10-05 04:45:02

DEPENDENCY INJECTION EXAMPLE USING SPRING的相关文章

Spring点滴七:Spring中依赖注入(Dependency Injection:DI)

Spring机制中主要有两种依赖注入:Constructor-based Dependency Injection(基于构造方法依赖注入) 和 Setter-based Dependency Injection(基于Setter方法依赖注入) 一.Contructor-based Dependency Injection(基于构造方法注入) 在bean标签中通过使用<constructor-arg />标签来实现 spring.xml <?xml version="1.0&qu

spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入

一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) set 注入.这篇随笔讲的是第一种构造方法注入(Constructor Injection). 其实DI(Dependency Injection)依赖注入你不妨反过来读:注入依赖也就是把"依赖"注入到一个对象中去.那么何为"依赖"呢?依赖就是讲一个对象初始化或者将实例

[LINK]List of .NET Dependency Injection Containers (IOC)

http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx I'm trying to expand my mind around dependency injection in .NET (beyond the two frameworks I've personally used) and an starting to put together a list of .NET Dependency I

IoC(Inversion of Control)控制反转和 DI(Dependency Injection)依赖注入

首先想说说IoC(Inversion of Control,控制倒转).这是spring的核心,贯穿始终.所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系.这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好.qq号.电话号.ip号.iq号---,想办法认识她们,投其所好送其所要,然后嘿嘿--这个过程是复杂深奥的,我们必须自己设计和面对每个环节.传统的程序开发也是如此,在

Inversion of Control Containers and the Dependency Injection pattern--Martin Fowler

原文地址:https://martinfowler.com/articles/injection.html n the Java community there's been a rush of lightweight containers that help to assemble components from different projects into a cohesive application. Underlying these containers is a common pat

Dependency Injection in ASP.NET Web API 2

What is Dependency Injection? A dependency is any object that another object requires. For example, it's common to define a repository that handles data access. Let's illustrate with an example. First, we'll define a domain model: public class Produc

Srping - bean的依赖注入(Dependency injection)

目录 1 概述 2 两种基本的依赖注入方式 2.1 构造函数方式 2.2Setter方式 3 其他依赖注入功能 3.1 <ref/>标签引用不同范围的bean 3.2 内部bean 3.3 集合注入 3.4 集合合并 3.5 强类型集合注入 3.6 null和空字符串 3.7 p-namespace方式配置属性注入 3.8 c-namespace方式配置构造函数参数注入 3.9 嵌套属性注入 1 概述 这篇文章主要就是讲解Spring的bean之间依赖注入的方法,本文不讲原理,只涉及用法. 在

Inversion of Control Containers and the Dependency Injection pattern(控制反转和依赖注入模式)

本文内容 Components and Services A Naive Example Inversion of Control Forms of Dependency Injection Constructor Injection with PicoContainer Setter Injection with Spring Interface Injection Using a Service Locator Using a Segregated Interface for the Loc

Ioc模式(又称DI:Dependency Injection 依赖注射)

分离关注( Separation of Concerns : SOC)是Ioc模式和AOP产生最原始动力,通过功能分解可得到关注点,这些关注可以是 组件Components, 方面Aspects或服务Services. 从GoF设计模式中,我们已经习惯一种思维编程方式:Interface Driven Design 接口驱动,接口驱动有很多好处,可以提供不同灵活的子类实现,增加代码稳定和健壮性等等,但是接口一定是需要实现的,也就是如下语句迟早要执行: AInterface a = new AIn