Spring DI 简单案例

Posted GoldenaArcher

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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();
    
    

    新的实现类:

    package springdemo;
    
    public class HappyFortuneService implements FortuneService 
    
        @Override
        public String getFortune() 
            return "Today is your lucky day";
        
    
    
    

    修改之前的 interface:

    package springdemo;
    
    public interface Coach 
        public String getDailyWorkout();
        
        public String getDailyFortune();
    
    
    package springdemo;
    
    public class BaseballCoach implements Coach 
    
        @Override
        public String getDailyWorkout() 
            return "Spend 30 minutes on batting practice.";
        
    
        @Override
        public String getDailyFortune() 
            return null;
        
    
    
    package springdemo;
    
    public class TrackCoach implements Coach 
    
        @Override
        public String getDailyWorkout() 
            return "Run a hrad 5k.";
        
    
        @Override
        public String getDailyFortune() 
            return null;
        
    
    
    
  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();
        
    
    
    
  3. 在 Spring 配置文件中注入依赖

        <bean id="myFortune" class="springdemo.HappyFortuneService"></bean>
        <!-- id is like an alias -->
        <bean id="myCoach" class="springdemo.TrackCoach">
            <constructor-arg ref="myFortune" />
        </bean>
    

这时候运行结果如下:

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

HappyFortuneService myFortuneService = new HappyFortuneService();
BaseballCoach myCoach = new BaseballCoach(myFortuneService);

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();
        
    
    
    
  2. 在 Spring 配置文件中完成依赖注入

    <!-- define the dependency -->
    <bean id="myFortuneService" class="springdemo.HappyFortuneService"></bean>
    
    <bean id="myCricketCoach" class="springdemo.CricketCoach">
    	<!-- set up setter injection -->
    	<!-- name must be identical to the property in object -->
    	<property name="fortuneService" ref="myFortuneService" />
    </bean>
    

    对应新的 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();
        
    
    
    

运行结果:

注入字面值

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();
        
    
    
    
  2. 在 Spring 配置文件中完成依赖注入

        <bean id="myCricketCoach" class="springdemo.CricketCoach">
            <!-- set up setter injection -->
            <!-- name must be identical to the property in object -->
            <property name="fortuneService" ref="myFortuneService" />
            <property name="emailAddress" value="test@test.com"></property>
            <property name="team" value="Yankee"></property>
        </bean>
    

    更新主函数:

    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();
        
    
    
    

运行结果:

通过配置文件注入字面值

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

开发流程如下:

  1. 新建属性文件

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

  3. 🚰属性文件

    <!-- load the properties files: sport.properties -->
    <context:property-placeholder location="classpath:sport.properties" />
    
        <bean id="myCricketCoach" class="springdemo.CricketCoach">
    	<!-- set up setter injection -->
    	<!-- name must be identical to the property in object -->
    	<property name="fortuneService" ref="myFortuneService" />
    	
    	<!-- <property name="emailAddress" value="test@test.com"></property> -->
    	<!-- <property name="team" value="Yankee"></property> -->
    	<property name="emailAddress" value="$foo.email" />
    	<property name="team" value="$foo.team" />
    	
    </bean>
    
    

运行结果如下:

以上是关于Spring DI 简单案例的主要内容,如果未能解决你的问题,请参考以下文章

Spring IoC基于XML的DI详细配置全解两万字

Spring随笔(06)

Spring——DI配合接口编程案例

Spring依赖注入 DI

关于Spring IOC (DI-依赖注入),你需要知道的 案例版

spring security 入门案例