【前面的话】

Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring。不知道为什么对Spring有一种莫名的喜欢感,也许是因为他的名字,有一种希望的感觉。

Spring学习过程中的总结和心得,本文介绍了在初次学习Spring的时候,对于依赖注入的理解,希望有时间可以进行更深入的学习。请选择性阅读。

本文由牲口TT在博客园首次发表,转载请保持文章的完整性并注明:
作者:牲口TT
链接:http://www.cnblogs.com/xt0810/p/3593853.html

Spring介绍】

Spring Framework是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做依赖注入(Dependency Injection,简称DI),还有一种方式叫“依赖查找”(Dependency Lookup)。通过控制反转,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用传递给它。也可以说,依赖被注入到对象中。

【依赖注入】

在学习Spring的时候,总是会遇到这个名词,就是依赖注入,所以首先学习什么是依赖注入。通过几个例子,说明什么是依赖注入,什么是spring下的依赖注入。

我们举一个Person开car的例子,希望通过这个例子可以更好的学习和理解什么是依赖注入。当然举得例子都是很简单的情形,在实际项目中可能要比这些复杂的多。

一、第一种情形:紧耦合情形,开宝马。

1. 分析如下:

定义三个类,Person.java、BaoMa.java、MainTest.java。如下面的代码,Person在它的构造函数中创建了Baoma对象,这就让Person类和Baoma类紧密的耦合在了一起,而且现在Person类只能开宝马,如果现在想要开奥迪,Person类是不能够处理的,除非修改Person这个类,这就使得两个类在紧耦合的情况下逻辑变得不够清晰,如果业务逻辑复杂,这些紧耦合的情形就会更多,带来代码难以测试,难以复用,难以理解等很多弊端。再加上让Person类来管理Baoma类的对象创建也是不合理的,因为面向对象的思想来说,Person类是没有管理Baoma类的对象的职责的。

2. 代码如下:

1)Person.java

 public class Person {
private BaoMa baoma;
public Person(){
baoma=new BaoMa();//Person和Baoma这个类紧耦合
}
public void driver(){
baoma.GuaDang();
baoma.CaiYouMen();
baoma.DaFangXiang();
}
}

2)BaoMa.java

public class BaoMa {
public void GuaDang(){
System.out.println("我是宝马车,我在进行挂档");
}
public void CaiYouMen(){
System.out.println("我是宝马车,我在进行踩油门");
}
public void DaFangXiang(){
System.out.println("我是宝马车,我在进行打方向盘");
}
}

3)MainTest.java

public class MainTest {
public static void main(String[] args){
Person boy =new Person();
boy.driver();
}
}

3.  运行结果:

我是宝马车,我在进行挂档
我是宝马车,我在进行踩油门
我是宝马车,我在进行打方向盘

二、第一种情形:紧耦合情形,开奥迪。

1.  分析如下:

从上面的代码中,我们如果想要开奥迪,只能对Person类进行修改,依次类推,如果开车人每次想要开的车不同,就需要每次对于Person类进行修改,这对于Person类来说是不合理的,Person类只关心我要开车,我有一个driver方法,我每次想要开车就是调用driver方法,所以这种紧耦合的编码是不够理想的。

2.  代码如下:

1)  Person.java

 public class Person {
private AuDi audi;
public Person(){
audi=new AuDi();
}
public void driver(){
audi.GuaDang();
audi.CaiYouMen();
audi.DaFangXiang();
}
}

2)   AuDi.java

 public class AuDi {
public void GuaDang(){
System.out.println("我是奥迪车,我在进行挂档");
}
public void CaiYouMen(){
System.out.println("我是奥迪车,我在进行踩油门");
}
public void DaFangXiang(){
System.out.println("我是奥迪车,我在进行打方向盘");
}
}

3)   MainTest.java

 public class MainTest {
public static void main(String[] args){
Person boy =new Person();
boy.driver();
}
}

3.  运行结果:

 我是奥迪车,我在进行挂档
我是奥迪车,我在进行踩油门
我是奥迪车,我在进行打方向盘

三、第二种情形:简单的依赖注入情形。

1.  分析如下:

在java的设计思想中,依赖注入的核心思想就是这种具体类之间的依赖,尽量转换成抽象依赖,也就是如下代码一样,Person类的依赖于抽象的Car类,而不是具体的Baoma类或者具体的AuDi类,分析见代码注释。

2.  代码如下:

1) Person.java

 public class Person {
private Car car;
public Person(Car car){//构造器注入,传入的是car,也就是一个所有车型都必须实现的接口
this.car =car;//这里可以响应奥迪,宝马等任何一种车的实现。
}//这里Person类没有与任何特定类型的车发生耦合,对于Person来说,任何一种特定的车,只需要实现Car接口即可。具体是哪一种车型,对Person来说无关紧要。
public void driver(){
car.GuaDang();
car.CaiYouMen();
car.DaFangXiang();
}
}

2)  Car.java

 public interface Car {
public abstract void GuaDang();
public abstract void CaiYouMen();
public abstract void DaFangXiang();
}

3)  AuDi.java

 public class AuDi implements Car {
public void GuaDang(){
System.out.println("我是奥迪车,我在进行挂档");
}
public void CaiYouMen(){
System.out.println("我是奥迪车,我在进行踩油门");
}
public void DaFangXiang(){
System.out.println("我是奥迪车,我在进行打方向盘");
}
}

4)  MainTest.java

 public class MainTest {
public static void main(String[] args){
AuDi audi=new AuDi();
Person boy =new Person(audi);
boy.driver();
}
}

3.  运行结果:

 我是奥迪车,我在进行挂档
我是奥迪车,我在进行踩油门
我是奥迪车,我在进行打方向盘

四、第三种情形:Spring的依赖注入情形。

1.  分析如下:

通过上面的说明,现在对于依赖注入应该有一个较好的理解了,那么Spring是如何实现IOC的?

通过依赖注入,对象的依赖关系将由负责协调系统中各个对象的第三方组件在创建对象时设定。对象无需自行创建或管理它们的依赖关系——依赖关系将自动注入到需要它们的对像中去。Spring就是这样的第三方组件,通过使用Spring框架,使得类之间的依赖关系通过Spring来进行管理。

具体的Spring进行依赖注入的方式和方法有时间在进行学习总结,今天只是对于Spring依赖注入的理解学习。

2.  代码如下:

1)Person.java

 public class Person {
private Car car;
public Person(Car car){//构造器注入,传入的是car,也就是一个所有车型都必须实现的接口
this.car =car;//这里可以响应奥迪,宝马等任何一种车的实现。
}//这里Person类没有与任何特定类型的车发生耦合,对于Person来说,任何一种特定的车,只需要实现Car接口即可。具体是哪一种车型,对Person来说无关紧要。
public void driver(){
car.GuaDang();
car.CaiYouMen();
car.DaFangXiang();
}
}

2) Car.java

 public interface Car {
public abstract void GuaDang();
public abstract void CaiYouMen();
public abstract void DaFangXiang();
}

3) AuDi.java

 public class AuDi implements Car {
public void GuaDang(){
System.out.println("我是奥迪车,我在进行挂档");
}
public void CaiYouMen(){
System.out.println("我是奥迪车,我在进行踩油门");
}
public void DaFangXiang(){
System.out.println("我是奥迪车,我在进行打方向盘");
} }

4) cartest.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"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean id="cartest" class="Person">
<constructor-arg ref="Car" />
</bean>
<bean id="Car" class="AuDi" />
</beans>

5)MainTest.java

 import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainTest {
public static void main(String[] args){
ApplicationContext context = new ClassPathXmlApplicationContext("cartest.xml");
Person boy =(Person) context.getBean("cartest");
boy.driver();
}
}

3.  运行结果:

 我是奥迪车,我在进行挂档
我是奥迪车,我在进行踩油门
我是奥迪车,我在进行打方向盘

【注意问题】

在编写上面的第四中的代码,需要注意一些问题,对于新手来说,可能会遇到错误。在这里说明一下:

一、首先需要导入如下的jar包。

  1. org.springframework.context-3.0.2.RELEASE.jar(点击可下载)
  2. org.springframework.beans-3.0.2.RELEASE.jar(点击可下载)
  3. org.springframework.core-3.0.2.RELEASE.jar(点击可下载)
  4. commons-logging-1.0.4.jar(点击可下载)
  5. org.springframework.asm-3.0.1.RELEASE-A.jar(点击可下载)
  6. org.springframework.expression-3.0.1.RELEASE-A.jar(点击可下载)

二、代码的结构如下图:

红线的地方在同一目录下。

三、可能遇到的错误

1. 错误:

The type org.springframework.core.NestedRuntimeException cannot be resolved. It is indirectly referenced from required .class files

解决办法:

导入:org.springframework.core-3.0.2.RELEASE

2.  错误:

Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory

解决办法:

导入:commons-logging-1.0.4

3.  错误:

Caused by: java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor

解决办法:

导入:org.springframework.asm-3.0.1.RELEASE-A

4.  错误:

org.springframework.expression.PropertyAccessor

解决办法:

导入:org.springframework.expression-3.0.1.RELEASE-A

【参考资料】

1. 《Spring in action》 Craig Walls著 耿渊 张卫滨译

【后面的话】

总是想学习很多东西,但是每次都不能够很好的完成的时候,或多或少总是很失望,我要好好学习。

分享:

1.读书,读到倦,网上有很多方法,但你从来沉不下心看。
     2.学习,学到疼,网上有很多方法,但你从来沉不下心看。
     3.开口说话,冷场也要说话,脸皮薄也要说话,挨打也要说话。
     4.如果你现在不知道做什么,至少你还可以先从做一个牛逼的学生开始。
     5.更漂亮更有趣的女孩,五年以后再找。
     6.承诺是鞭子,不是兴奋剂。
     7.年纪大了,也不要说什么心如死灰。

——TT

Spring学习(一)——Spring中的依赖注入简介的更多相关文章

  1. Spring学习(一)——Spring中的依赖注入简介【转】

      [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring. ...

  2. Spring学习笔记(8)——依赖注入

    spring依赖注入使用构造器注入使用属性setter方法注入使用Field注入(用于注解方式) 注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发 ...

  3. Spring学习-理解IOC和依赖注入

    最近刚买了一本介绍ssm框架的书,里面主要对Mybatis.spring.springmvc和redis做了很多的讲解,个人觉得虽然有的内容我看不懂,但是整体上还是不错的.最近正在学习中,一边学习一边 ...

  4. Spring学习:简单实现一个依赖注入和循环依赖的解决

    依赖注入 什么是依赖注入 使用一个会创建和查找依赖对象的容器,让它负责供给对象. 当a对象需要b对象时,不再是使用new创建,而是从容器中获取,对象与对象之间是松散耦合的关系,有利于功能复用. 依赖: ...

  5. Spring:Spring-IOC容器、DI依赖注入简介

    Spring容器到底是什么? 从概念上讲:Spring 容器是 Spring 框架的核心,是用来管理对象的.容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁. 从具象化 ...

  6. Spring学习02——控制反转、依赖注入

    有两个人,张三和李四 package com.su.service; public class ZhangSan implements Tester{ public void test(){ Syst ...

  7. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

  8. 类比Spring框架来实现OC中的依赖注入

    如果你之前使用过JavaEE开发中的Spring框架的话,那么你一定对依赖注入并不陌生.依赖注入(DI: Dependency Injection)是控制反转(IoC: Inversion of Co ...

  9. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

随机推荐

  1. IE的CSS渲染跟其它浏览器有什么不同

    由于IE系浏览器对标准的支持不够好,导致Web开发中经常需要去处理浏览器兼容性问题,特别有些莫名其妙的问题很让人头疼,今天要说这个问题就是这样的,先从插入CSS的三种方法说起: 外部样式(Extern ...

  2. [ZJOI2010]排列计数 (组合计数/dp)

    [ZJOI2010]排列计数 题目描述 称一个1,2,...,N的排列P1,P2...,Pn是Magic的,当且仅当2<=i<=N时,Pi>Pi/2. 计算1,2,...N的排列中有 ...

  3. 洛谷:P3809 【模板】后缀排序(后缀数组模板)

    P3809 [模板]后缀排序 题目链接:https://www.luogu.org/problemnew/show/P3809 题目背景 这是一道模板题. 题目描述 读入一个长度为 nn 的由大小写英 ...

  4. [vim]大小写转换

    http://babybandf.blog.163.com/blog/static/619935320110121134826/ ~ 将光标下的字母改变大小写 3~ 将光标位置开始的3个字母改变其大小 ...

  5. 代码Review发现问题

    FrmMain.cs中存在问题 1. int i=0 设定为了全局常量且未在类顶部,出现问题时不好查找 i 属于常用临时变量,设定全局变量容易引起混乱 2.定义的全局变量但仅在一处方法中使用,定义全局 ...

  6. web开发中防止SQL注入

    一.SQL注入简介 SQL注入是比较常见的网络攻击方式之一,它不是利用操作系统的BUG来实现攻击,而是针对程序员编写时的疏忽,通过SQL语句,实现无账号登录,甚至篡改数据库. 二.SQL注入攻击的总体 ...

  7. Java反射中method.isBridge() 桥接方法

    桥接方法是 JDK 1.5 引入泛型后,为了使Java的泛型方法生成的字节码和 1.5 版本前的字节码相兼容,由编译器自动生成的方法.我们可以通过Method.isBridge()方法来判断一个方法是 ...

  8. jmeter进行http压力测试(图文小教程)

    下载地址:http://jmeter.apache.org/download_jmeter.cgi JMeter基于Java开发,需要系统有安装JDK环境.解压后进入bin目录,点击jmeter.ba ...

  9. UIImageView与UIScrollView的关系图

        UIImageView与UIScrollView的关系图           https://www.evernote.com/shard/s227/sh/0af9f23c-08e6-4be6 ...

  10. B. Complete the Word(Codeforces Round #372 (Div. 2)) 尺取大法

    B. Complete the Word time limit per test 2 seconds memory limit per test 256 megabytes input standar ...