一:这里先说一下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的代码如下:

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

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

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

//Query接口的代码如下:

 package com.qls.inter;

 /**
* Created by ${秦林森} on 2017/6/2.
*/
public interface Query {
void query();
void embark();
}

//Knight的代码如下:

 package com.qls.inter;

 /**
* Created by ${秦林森} on 2017/6/2.
*/
public interface Knight {
void embarkOnQuest();
}

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

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

 package com.qls.impl;

 import com.qls.inter.Query;

 import java.io.PrintStream;

 /**
* Created by ${秦林森} on 2017/6/2.
*/
public class SlayDragonQuest implements Query{
private PrintStream stream; public SlayDragonQuest(PrintStream stream) {
this.stream = stream;
}
@Override
public void embark(){
stream.println("Embarking on quest to slay the dragon");
stream.println("ouyangfeng is the most beautiful woman in the world.");
}
@Override
public void query(){
System.out.println("slay dragon quest");
}
}

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

 package com.qls.impl;

 import com.qls.inter.Query;

 import java.io.PrintStream;

 /**
* Created by ${秦林森} on 2017/6/3.
*/
public class SearchHillQuest implements Query{
private PrintStream stream; public SearchHillQuest(PrintStream stream) {
this.stream = stream;
} @Override
public void query() { } @Override
public void embark() {
stream.println("the hero search the hill where the damsel was missing");
}
}

//BraveKnight的代码如下:

 package com.qls.impl;

 import com.qls.inter.Knight;
import com.qls.inter.Query;
import org.springframework.context.annotation.Configuration; /**
* Created by ${秦林森} on 2017/6/2.
*/ public class BraveKnight implements Knight{
private Query query; public BraveKnight(Query query) {
this.query = query;
} @Override
public void embarkOnQuest() {
query.embark();
}
}

//测试类的代码如下:

 package com.qls.test;

 import com.qls.inter.Knight;
import org.springframework.context.support.ClassPathXmlApplicationContext; /**
* Created by ${秦林森} on 2017/6/2.
*/
public class Test {
public static void main(String[] args) {
/**
* 加载配置文件的方式:在src下直接写配置文件的名即可,
* 不直接在src下要把前面的包名加上。包名的前面可加也可以不加斜杠/
*/
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("/com/config/spring-julythird.xml");
// ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("com/config/spring-julythird.xml");
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-julysecond.xml");
Knight knight = context.getBean(Knight.class);
knight.embarkOnQuest();
context.close(); }
}

spring in action学习笔记一:DI(Dependency Injection)依赖注入之CI(Constructor Injection)构造器注入的更多相关文章

  1. Spring in Action 学习笔记二-DI

    装配bean 2015年10月9日 9:49             Sprng中,对象无需自己负责查找或创建其关联的其他对象.相关,容器负责吧需要相互协作的对象引用赋予各个对象. 创建应用对象之间协 ...

  2. Spring in Action 学习笔记一

    Spring 核心       Spring的主要特性仅仅是 依赖注入DI和面向切面编程AOP       JavaBean 1996.12 Javav 规范针对Java定义了软件组件模型,是简单的J ...

  3. spring in action学习笔记十五:配置DispatcherServlet和ContextLoaderListener的几种方式。

    在spring in action中论述了:DispatcherServlet和ContextLoaderListener的关系,简言之就是DispatcherServlet是用于加载web层的组件的 ...

  4. spring in action 学习笔记十四:用纯注解的方式实现spring mvc

    在讲用纯注解的方式实现springmvc之前先介绍一个类:AbstractAnnotationDispatcherServletInitializer.这个类的作用是:任何一个类继承AbstractA ...

  5. Spring in Action 学习笔记三-AOP

    面向切面的Spring 2015年10月9日 11:30             屏幕剪辑的捕获时间: 2015-10-9 14:30             屏幕剪辑的捕获时间: 2015-10-9 ...

  6. spring in action学习笔记十六:配置数据源的几种方式

    第一种方式:JNDI的方式. 用xml配置的方式的代码如下: 1 <jee:jndi-lookup jndi-name="/jdbc/spittrDS" resource-r ...

  7. spring in action 学习笔记九:如何证明在scope为prototype时每次创建的对象不同。

    spring 中scope的值有四个:分别是:singleton.prototype.session.request.其中session和request是在web应用中的. 下面证明当scope为pr ...

  8. spring in action学习笔记七:@Conditional注解的用法

    @Profile注解是@Conditional注解的一个例子.即@Profile也是用@Conditional注解来实现的. 必须让条件实现Condition这个接口. 下面的案例讲如果环境中有mag ...

  9. spring in action 学习笔记五:@Autowired这个注解如何理解

    @Autowired这个注解的意思就是自动装配.他把一个bean对象自动装配到另一个对象中.下面的案例证明了spring的自动装配. 定义一个Sixi类.代码如下: package com.qls.a ...

随机推荐

  1. Java高并发之同步异步

    1.概念理解: 2.同步的解决方案: 1).基于代码 synchronized 关键字 修饰普通方法:作用于当前实例加锁,进入同步代码前要获得当前实例的锁. 修饰静态方法:作用于当前类对象加锁,进入同 ...

  2. php如何连接mysql,并操纵后台服务器运作的过程

    PHP,一个嵌套的缩写名称,是英文超级文本预处理语言(PHP:Hypertext Preprocessor)的缩写.PHP 是一种 HTML 内嵌式的语言,PHP与微软的ASP颇有几分相似,都是一种在 ...

  3. ThinkPHP路由去掉隐藏URL中的index.php

    官方默认的.htaccess文件 <IfModule mod_rewrite.c> Options +FollowSymlinks -Multiviews RewriteEngine On ...

  4. 【js】【跨域问题】前后端分离的跨域问题

    最近在研究nodejs,php的前后端分离相关东西,在调用接口的时候碰到一些跨域的问题,经过一段时间的摸索,总结出来的一些东西 php采用的是yii框架,登录的机制或者调用接口都需要前端传递cooki ...

  5. php图片压缩-高清晰度

    php高清晰度无损压缩 经常会用到把上传的大图片压缩,特别是体积,在微信等APP应用上,也默认都是有压缩的,那么,怎么样对图片大幅度压缩却仍能保持较高的清晰度呢? 压缩通常是有按比例缩放,和指定宽度压 ...

  6. 3 web框架

    web框架 Web框架(Web framework)是一种开发框架,用来支持动态网站.网络应用和网络服务的开发.这大多数的web框架提供了一套开发和部署网站的方式,也为web行为提供了一套通用的方法. ...

  7. Android 布局跟着NAVIGATION_BAR 重新布局

    要想让自己的布局跟着NAVIGATION_BAR 的变化重新布局,就不要设置 SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION. 这个FLAG. 这个flag 设置之后,你的 ...

  8. 分别用反射、编程接口的方式创建DataFrame

    1.通过反射的方式 使用反射来推断包含特定数据类型的RDD,这种方式代码比较少,简洁,只要你会知道元数据信息时什么样,就可以使用了 代码如下: import org.apache.spark.sql. ...

  9. 有哪些值得一读的优秀开源 JS 代码

    有哪些值得一读的优秀开源 JS 代码 采纳 首先,没有“必须”读的源代码(我发现我特喜欢说首先……),因为读源代码不是做功课,只有用到或是非常好奇才会去读,当成“日常”去做是没有意义的. 当然有些人会 ...

  10. Mac 小技巧

    本文的大部分技巧来自于池建强老师的<MacTalk.人生元编程>,感谢他的辛苦付出,本文多系整理而已. 终端输入说英语 说英语时我们当然希望有标准发音.在Mac中不需要字典,直接在终端里输 ...