• Spring DI 简单案例


    Spring DI 简单案例

    本案例中使用 XML 文档配置进行 Dependency Injection 的实现。

    Spring 容器的主要功能包括:

    • 创建和管理对象 (Inversion of Control,IoC)
    • 注入对象的依赖 (Dependency Injection,DI)

    这个案例中其他的代码沿用了 Spring IoC 简单案例 部分代码。

    本案例中需要两个功能:

    • 提供每日锻炼(已经在 IoC 中实现的功能)

    • 提供每日幸运语

      这一部分需要实现一个新的帮助函数(依赖):ForuneService

    Spring 中提供了好几种依赖注入的方法,主要的有三种:

    • 构造函数注入 construction injection
    • setter 注入 setter injection
    • 注解中使用 auto wiring

    本案例中会使用 构造函数和 setter 注入进行实现。

    构造函数注入

    开发过程:

    1. 定义依赖 interface 和实现类

      FortuneService interface:

      package springdemo;
      
      public interface FortuneService {
          public String getFortune();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5

      新的实现类:

      package springdemo;
      
      public class HappyFortuneService implements FortuneService {
      
          @Override
          public String getFortune() {
              return "Today is your lucky day";
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10

      修改之前的 interface:

      package springdemo;
      
      public interface Coach {
          public String getDailyWorkout();
          
          public String getDailyFortune();
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      package springdemo;
      
      public class BaseballCoach implements Coach {
      
          @Override
          public String getDailyWorkout() {
              return "Spend 30 minutes on batting practice.";
          }
      
          @Override
          public String getDailyFortune() {
              return null;
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      package springdemo;
      
      public class TrackCoach implements Coach {
      
          @Override
          public String getDailyWorkout() {
              return "Run a hrad 5k.";
          }
      
          @Override
          public String getDailyFortune() {
              return null;
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
    2. 在实现类中创造一个构造函数让 Spring 实现注入

      package springdemo;
      
      public class TrackCoach implements Coach {
      
          // define a private field for the dependency
          private FortuneService fortuneService;
          
          // define a constructor for dependency injection
          public TrackCoach(FortuneService fortuneService) {
              this.fortuneService = fortuneService;
          }
          
          @Override
          public String getDailyWorkout() {
              return "Run a hrad 5k.";
          }
      
          @Override
          public String getDailyFortune() {
              // use my fortuneService to get a fortune
              return fortuneService.getFortune();
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
    3. 在 Spring 配置文件中注入依赖

          <bean id="myFortune" class="springdemo.HappyFortuneService">bean>
          
          <bean id="myCoach" class="springdemo.TrackCoach">
              <constructor-arg ref="myFortune" />
          bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5

    这时候运行结果如下:

    constructor injection

    XML 中的内容最终在 Spring 内部转化为对应的 Java 代码,创建对应的对象和传入参数:

    HappyFortuneService myFortuneService = new HappyFortuneService();
    BaseballCoach myCoach = new BaseballCoach(myFortuneService);
    
    • 1
    • 2

    Setter 注入

    这里会创建一个新的类以及新的主函数进行实现。

    开发流程

    1. 在类中创建 setter 进行依赖注入

      package springdemo;
      
      public class CricketCoach implements Coach {
          private FortuneService fortuneService;
      
          public FortuneService getFortuneService() {
              return fortuneService;
          }
      
          public void setFortuneService(FortuneService fortuneService) {
              System.out.println("CricketCoach: inside setter method");
              this.fortuneService = fortuneService;
          }
      
          public CricketCoach() {
              System.out.println("CricketCoach: inside no-arg constructor");
          }
      
          @Override
          public String getDailyWorkout() {
              return "Practice fast bowling for 15 minutes";
          }
      
          @Override
          public String getDailyFortune() {
              return fortuneService.getFortune();
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28
      • 29
    2. 在 Spring 配置文件中完成依赖注入

      
      <bean id="myFortuneService" class="springdemo.HappyFortuneService">bean>
      
      <bean id="myCricketCoach" class="springdemo.CricketCoach">
      	
      	
      	<property name="fortuneService" ref="myFortuneService" />
      bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8

      对应新的 Main 函数:

      package springdemo;
      
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class SetterDemoApp {
      
          public static void main(String[] args) {
              // load the spring configuration file
              ClassPathXmlApplicationContext context = 
                      new ClassPathXmlApplicationContext("applicationContext.xml");
                      
              // retrieve bean from spring container
              Coach theCoach = context.getBean("myCricketCoach", Coach.class);
                      
              // call methods on the bean
              System.out.println(theCoach.getDailyWorkout());
                      
              // call new method for fortune
              System.out.println(theCoach.getDailyFortune());
                      
              // close the context
              context.close();
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25

    运行结果:

    setter injection

    注入字面值

    Spring 也可以通过配置文件注入字面值。

    开发过程:

    1. 在类中创建 setter 进行依赖注入

      新增邮箱和队伍属性:

      package springdemo;
      
      public class CricketCoach implements Coach {
          private FortuneService fortuneService;
          
          private String emailAddress;
      
          private String team;
      
          public FortuneService getFortuneService() {
              return fortuneService;
          }
      
          public CricketCoach() {
              System.out.println("CricketCoach: inside no-arg constructor");
          }
          
          public void setFortuneService(FortuneService fortuneService) {
              System.out.println("CricketCoach: inside setter method");
              this.fortuneService = fortuneService;
          }
          
          public String getEmailAddress() {
              return emailAddress;
          }
      
          public void setEmailAddress(String emailAddress) {
              this.emailAddress = emailAddress;
          }
      
          public String getTeam() {
              return team;
          }
      
          public void setTeam(String team) {
              this.team = team;
          }
      
          @Override
          public String getDailyWorkout() {
              return "Practice fast bowling for 15 minutes";
          }
      
          @Override
          public String getDailyFortune() {
              return fortuneService.getFortune();
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 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
      • 35
      • 36
      • 37
      • 38
      • 39
      • 40
      • 41
      • 42
      • 43
      • 44
      • 45
      • 46
      • 47
      • 48
      • 49
    2. 在 Spring 配置文件中完成依赖注入

          <bean id="myCricketCoach" class="springdemo.CricketCoach">
              
              
              <property name="fortuneService" ref="myFortuneService" />
              <property name="emailAddress" value="test@test.com">property>
              <property name="team" value="Yankee">property>
          bean>
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7

      更新主函数:

      package springdemo;
      
      import org.springframework.context.support.ClassPathXmlApplicationContext;
      
      public class SetterDemoApp {
      
          public static void main(String[] args) {
              // load the spring configuration file
              ClassPathXmlApplicationContext context = 
                      new ClassPathXmlApplicationContext("applicationContext.xml");
                      
              // retrieve bean from spring container
              CricketCoach theCoach = context.getBean("myCricketCoach", CricketCoach.class);
                      
              // call methods on the bean
              System.out.println(theCoach.getDailyWorkout());
                      
              // call new method for fortune
              System.out.println(theCoach.getDailyFortune());
              
              System.out.println(theCoach.getEmailAddress());
              System.out.println(theCoach.getTeam());
                      
              // close the context
              context.close();
          }
      
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
      • 28

    运行结果:

    inject literal value

    通过配置文件注入字面值

    除了直接在 Spring 配置文件中注入字面值之外,Spring 还能通过在 Spring 配置文件中读取其他配置文件的方式,更加动态地获取字面值。

    开发流程如下:

    1. 新建属性文件

      foo.email=email@properties.com
      foo.team=Team From Properties File
      
      • 1
      • 2
    2. 在 Spring 配置文件中加载属性文件

    3. 🚰属性文件

      
      <context:property-placeholder location="classpath:sport.properties" />
      
          <bean id="myCricketCoach" class="springdemo.CricketCoach">
      	
      	
      	<property name="fortuneService" ref="myFortuneService" />
      	
      	
      	
      	<property name="emailAddress" value="${foo.email}" />
      	<property name="team" value="${foo.team}" />
      	
      bean>
      
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

    运行结果如下:

    read value from property file

  • 相关阅读:
    磁盘空间满问题排查方法
    Python---多线程
    [附源码]计算机毕业设计病人跟踪治疗信息管理系统Springboot程序
    【MySQL】索引的分类
    mock 点击图片显示Too big of an image!
    JS——垃圾回收的原理
    理解『注意力机制』的本质
    SpringCloud系列(14)--Eureka服务发现(Discovery)
    安装MySql8.0详细教程
    【二叉树】层数最深叶子节点的和
  • 原文地址:https://blog.csdn.net/weixin_42938619/article/details/127582220