zoukankan      html  css  js  c++  java
  • spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入

    一:这里先说一下DI(Dependency Injection)依赖注入有种表现形式:一种是CI(Constructor Injection)构造方法注入,另一种是SI(Set Injection) set 注入。这篇随笔讲的是第一种构造方法注入(Constructor Injection).

    其实DI(Dependency Injection)依赖注入你不妨反过来读:注入依赖也就是把"依赖"注入到一个对象中去。那么何为"依赖"呢?依赖就是讲一个对象初始化或者将实例化的时候需要另一个对象,我们把另一个对象成为"依赖"。如构造方法注入(Constructor Injection)就是把依赖当做构造方法的参数注入进去的。如:

    //Injection B to A. 我们把B称为依赖。一般情况下B是一个接口,这符合面向接口编程的规范。

    public A (B b){

    }

    二:使用依赖注入的好处是什么?

      1.DI(Dependency Injection)最大的好处是decoupling(解耦)。如上面的代码把B注入给A如果B是一个接口或者抽象类。只要任何一个类实现或者继承B都可以注入给A.因此可以达到解耦的目的。

      2. 依赖注入给谁?        

    dependencies injected into the objects that need them.(依赖注入给那些需要他们的对象。)

       3.在spring中怎么让依赖传入到被依赖的对象(看上面的代码:怎么把B传入到A中)?

     在这里我引用一下spring in action中的一段文字:(注:我下面的示例代码基本跟spring in action 的一样)

    The big question here is,how can you give SlayDragonQuest to BraveKnight ? And how can you give a PrintStream to SlayDragonQuest?

    The act of creating associations between application components is commonly referred to as wiring. 

    spring通过配置配置文件,配置bean的形式,完成装配,又装配实现把依赖注入给需要他们的对象中的。

    【我这里还想说明一下配置文件中的一个bean其实就对应一个javabean,也就是一个pojo对象,bean就是javabean的缩写形式而已】

     示例代码的目录结构如下图所示:

      上面中的带两个圈的配置文件想说明两个问题:

    一个是:new ClassPathXmlApplicationContext("spring-julysecond.xml");//注意这个.xml文件是在src目录下。

        new ClassPathXmlApplicationContext("com/config/spring-julythird.xml")//注意这个.xml文件在com.cofig这个文件下。

    另一个问题是DI的解耦问题:spring-julysecond.xml文件中注入的是SlayDragonQuest,spring-julythird.xml注入的是SearchHillQuest.在不改变代码的情况下看传入的Quest的实现类不同,从而打出的结果不同。

    spring-julysecond.xml的代码如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xsi:schemaLocation="http://www.springframework.org/schema/beans
     5 http://www.springframework.org/schema/beans/spring-beans.xsd">
     6     <!--this is constructor injection-->
     7     <!--the act of creating associations between application components is commonly referred to
     8     as wiring-->
     9     <bean id="knight" class="com.qls.impl.BraveKnight">
    10         <!-- collaborators and configuration for this bean go here -->
    11         <constructor-arg ref="query"></constructor-arg>
    12     </bean>
    13     <bean id="query" class="com.qls.impl.SlayDragonQuest">
    14         <!-- collaborators and configuration for this bean go here -->
    15         <constructor-arg value="#{T(System).out}"/>
    16     </bean>
    17     <!-- more bean definitions go here -->
    18 </beans>

    //spring-julythird.xml的代码如下:

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <beans xmlns="http://www.springframework.org/schema/beans"
     3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     4        xsi:schemaLocation="http://www.springframework.org/schema/beans
     5 http://www.springframework.org/schema/beans/spring-beans.xsd">
     6     <!--this is constructor injection-->
     7     <!--the act of creating associations between application components is commonly referred to
     8     as wiring-->
     9     <bean id="knight" class="com.qls.impl.BraveKnight">
    10         <!-- collaborators and configuration for this bean go here -->
    11         <constructor-arg ref="query"></constructor-arg>
    12     </bean>
    13     <bean id="query" class="com.qls.impl.SearchHillQuest">
    14         <constructor-arg value="#{T(System).out}"/>
    15     </bean>
    16     <!-- more bean definitions go here -->
    17 </beans>

    //Query接口的代码如下:

     1 package com.qls.inter;
     2 
     3 /**
     4  * Created by ${秦林森} on 2017/6/2.
     5  */
     6 public interface Query {
     7     void query();
     8     void embark();
     9 }
    10 
    11     

    //Knight的代码如下:

    1 package com.qls.inter;
    2 
    3 /**
    4  * Created by ${秦林森} on 2017/6/2.
    5  */
    6 public interface Knight {
    7     void embarkOnQuest();
    8 }

    //Query接口的实现类的代码如下:

    //首先是:SlayDragonQuest的代码如下:

     1 package com.qls.impl;
     2 
     3 import com.qls.inter.Query;
     4 
     5 import java.io.PrintStream;
     6 
     7 /**
     8  * Created by ${秦林森} on 2017/6/2.
     9  */
    10 public class SlayDragonQuest implements  Query{
    11     private PrintStream stream;
    12 
    13     public SlayDragonQuest(PrintStream stream) {
    14         this.stream = stream;
    15     }
    16     @Override
    17     public void embark(){
    18         stream.println("Embarking on quest to slay the dragon");
    19         stream.println("ouyangfeng is the most beautiful woman in the world.");
    20     }
    21     @Override
    22     public void query(){
    23         System.out.println("slay dragon quest");
    24     }
    25 }

    //其次是SearchHillQuest的代码如下:

     1 package com.qls.impl;
     2 
     3 import com.qls.inter.Query;
     4 
     5 import java.io.PrintStream;
     6 
     7 /**
     8  * Created by ${秦林森} on 2017/6/3.
     9  */
    10 public class SearchHillQuest implements Query{
    11     private PrintStream stream;
    12 
    13     public SearchHillQuest(PrintStream stream) {
    14         this.stream = stream;
    15     }
    16 
    17     @Override
    18     public void query() {
    19 
    20     }
    21 
    22     @Override
    23     public void embark() {
    24        stream.println("the hero search the hill where the damsel was missing");
    25     }
    26 }

    //BraveKnight的代码如下:

     1 package com.qls.impl;
     2 
     3 import com.qls.inter.Knight;
     4 import com.qls.inter.Query;
     5 import org.springframework.context.annotation.Configuration;
     6 
     7 /**
     8  * Created by ${秦林森} on 2017/6/2.
     9  */
    10 
    11 public class BraveKnight implements Knight{
    12     private Query query;
    13 
    14     public BraveKnight(Query query) {
    15         this.query = query;
    16     }
    17 
    18     @Override
    19     public void embarkOnQuest() {
    20         query.embark();
    21     }
    22 }

    //测试类的代码如下:

     1 package com.qls.test;
     2 
     3 import com.qls.inter.Knight;
     4 import org.springframework.context.support.ClassPathXmlApplicationContext;
     5 
     6 /**
     7  * Created by ${秦林森} on 2017/6/2.
     8  */
     9 public class Test {
    10     public static void main(String[] args) {
    11         /**
    12          * 加载配置文件的方式:在src下直接写配置文件的名即可,
    13          * 不直接在src下要把前面的包名加上。包名的前面可加也可以不加斜杠/
    14          */
    15 //        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/com/config/spring-julythird.xml");
    16 //        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/config/spring-julythird.xml");
    17         ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-julysecond.xml");
    18         Knight knight = context.getBean(Knight.class);
    19         knight.embarkOnQuest();
    20         context.close();
    21 
    22     }
    23 }

     

  • 相关阅读:
    基本目标与达成方法
    终于搞定在VS2010中将CString转换为const char*
    【HBase学习之一】HBase简介
    Origin2017画分组柱状图
    映射是什么?函数是什么?映射与函数的关系?
    PPT一次性禁用所有动画效果
    跨模态检索技术调研
    卷积核与特征提取
    深入理解卷积层,全连接层的作用意义
    cbow 与 skip-gram的比较
  • 原文地址:https://www.cnblogs.com/1540340840qls/p/6936581.html
Copyright © 2011-2022 走看看