文档章节

5.2 Spring核心机制--依赖注入

JerryPan
 JerryPan
发布于 2016/03/05 07:33
字数 1334
阅读 279
收藏 8

Spring的核心机制是依赖注入(Dependency Inversion),也成为控制反转。学习它之前先引入一个设计模式-工厂模式。

5.2.1  工厂模式

工厂模式是指当甲组件需要乙组件协助时,不直接创建乙组件的实例对象,而是通过乙组件的工厂创建,这样甲组件无需通过硬编码的方式与乙组件耦合,只需与乙组件的工厂耦合。

创建一个Java Project,命名为“FactoryExample”。在src文件夹下建立包face,在该包下建立接口Human,代码如下:

package face;
public interface Human {
    void eat();
    void walk();
}

 

在src文件夹下建立包iface,在该包下建立Chinese类和American类,分别实现Human接口。

Chinese.java代码如下:

package iface;
import face.Human;
public class Chinese implements Human{
    public void eat() {
        System.out.println("中国人很会吃!");
    }
    public void walk() {
        System.out.println("中国人健步如飞!");
    }
}

American.java代码如下:

package iface;
import face.Human;
public class American implements Human{
public void eat() {
System.out.println("美国人吃西餐!");
   }
  public void walk() {
 System.out.println("美国人经常坐车!");
   }
}

在src文件夹下建包factory,在该包内建立工厂类Factory,代码如下:

package factory;
import iface.American;
import iface.Chinese;
import face.Human;
public class Factory {
public Human getHuman(String name){
if(name.equals("Chinese")){
return new Chinese();
}else if(name.equals("American")){
return new American();
}else{
throw new IllegalArgumentException("参数不正确");
}
   }
}

在src文件夹下建包test,在该包内建立测试类Test,代码如下:

package test;
import face.Human;
import factory.Factory;
public class Test {
   public static void main(String[] args) {
  Human human=null;
  human=new Factory().getHuman("Chinese");
  human.eat();
  human.walk();
human=new Factory().getHuman("American");
  human.eat();
  human.walk();
   }
}

该程序为Java应用程序,直接运行可看出结果,如图5.2所示。

图5.2  工厂模式运行结果

 

5.2.2  依赖注入应用

上面讲到了工厂模式,Sping提供了更好的办法实现,就是依赖注入。

1. 为项目添加Spring开发能力

右击项目名,选择【MyEclipse】→【Add Spring Capabilities…】菜单项,将出现如图5.3所示的对话框,选中要应用的Spring的版本及所需的类库文件。

图5.3  选择Spring版本及类库对话框

 

选择结束后,单击【Next】按钮,出现如图5.4所示的界面。用于创建Spring的配置文件。

单击【Finish】按钮完成。项目的src文件夹下会出现名为applicationContext.xml的文件,这就是Spring的核心配置文件

 

图5.4  创建Spring的配置文件

 

2. 修改测试类

配置完成后,就可以修改Test类。对象ctx就相当于原来的Factory工厂,原来的Factory可以删除掉了。

package test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
import face.Human;
import factory.Factory;
public class Test {
    public static void main(String[] args) {
        ApplicationContext ctx=new FileSystemXmlApplicationContext("src/applicationContext.xml");
        Human human = null;   
        human = (Human) ctx.getBean("chinese");   
        human.eat();   
        human.walk();   
        human = (Human) ctx.getBean("american");   
        human.eat();   
        human.walk();   
    }
}

在applicationContext.xml配置如下

<bean id="chinese" class="iface.Chinese"></bean>
<bean id="american" class="iface.American"></bean>

id是ctx.getBean的参数值,一个字符串。class是一个类(包名+类名)。

human = (Human) ctx.getBean("american");
human = (Human) ctx.getBean("american");

3. 运行

运行该测试类,结果如图5.5所示。

图5.5  运行结果

5.2.3  注入的两种方式

所谓依赖注入,就是调用另一个对象时,无需在代码中创建被调用者,而是依赖于外部的注入。

1. 设置注入

设置注入是通过setter方法注入被调用者的实例。这种方法简单、直观,很容易理解,因而Spring的依赖注入被大量使用,下面举例说明。

创建一个Java Project,命名为“FactoryExample1”。在项目的src文件夹下建立下面的源文件。

Human的接口,Human.java,代码如下:

public interface Human {
void speak();
}

Language接口,Language.java,代码如下:

public interface Language {
public String kind();
}

下面是Human实现类Chinese.java代码:

public class Chinese implements Human{
   private Language lan; 
   public void speak() {
System.out.println(lan.kind());
   }
   public void setLan(Language lan) {
 this.lan = lan;
   }
}

下面是Language实现类English.java代码:

public class English implements Language{
   public String kind() {
return "中国人也会说英语!";
   }
}

下面通过Spring的配置文件来完成其对象的注入。代码如下:

<?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-2.0.xsd">
<!-- 定义第一个Bean,注入Chinese类对象 -->
<bean id="chinese" class="iface.Chinese">
<!-- property元素用来指定需要容器注入的属性,lan属性需要容器注入
ref就指向lan注入的id -->
<property name="lan" ref="english"></property>
</bean>
<!-- 注入English -->
<bean id="english" class="iface.English"></bean>
</beans>

 

测试代码如下:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class Test {
    public static void main(String[] args) {
    ApplicationContext ctx = new FileSystemXmlApplicationContext("src/applicationContext.xml");
    Human human = null;    
    human = (Human) ctx.getBean("chinese");    
    human.speak();  
    }
}

程序执行结果如图5.6所示。

图5.6  程序运行结果

 

2. 构造注入

这种方式在构造实例时,已经完成了属性的初始化。

例如,只要对前面的Chinese类进行简单的修改:

public class Chinese implements Human{
    private Language lan;
    public Chinese(){};
    // 构造注入所需要的带参数的构造函数
    public Chinese(Language lan){
        this.lan=lan;
    }
    public void speak() {
        System.out.println(lan.kind());
    }
}

 

配置文件也需要做简单的修改:

<?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-2.0.xsd">
    <!-- 定义第一个Bean,注入Chinese类对象 -->
    <bean id="chinese" class="iface.Chinese">
        <!-- 使用构造注入,为Chinese实例注入Language实例 -->
        <constructor-arg ref="english"></constructor-arg>
    </bean>
    <!-- 注入English -->
    <bean id="english" class="iface.English"></bean>
</beans>

 

附:目录《JavaEE基础实用教程》笔记说明

© 著作权归作者所有

共有 人打赏支持
JerryPan
粉丝 20
博文 54
码字总数 64891
作品 0
宁波
程序员
私信 提问
Java面试中常问的Spring方面问题(含答案)

Spring Framework 现在几乎已成为 Java Web 开发的标配框架。那么,作为 Java 程序员,你对 Spring 的主要技术点又掌握了多少呢?不妨用本文的问题来检测一下。 1、一般问题 1.1. 不同版本的...

Java猫
01/15
0
0
Java笔记——看完这个,打通Spring难度系数

写在前面经过一段时间的整理,希望读者看完后对自己的知识点有所帮助。 写过java的都知道:所有的对象都必须创建;或者说:使用对象之前必须先创建。而使用ioc之后,你就可以不再手动创建对象...

简祥
2018/09/14
0
0
【死磕 Spring】----- IOC 之深入理解 Spring IoC

版权声明:版权声明:转载前请留言获得作者许可,转载后标明作者 chenssy 和原文出处。原创不易,感谢您的支持 https://blog.csdn.net/chenssy/article/details/82343456 在一开始学习 Spri...

chenssy
2018/09/03
0
0
【死磕 Spring】—– IOC 之深入理解 Spring IoC

在一开始学习 Spring 的时候,我们就接触 IoC 了,作为 Spring 第一个最核心的概念,我们在解读它源码之前一定需要对其有深入的认识,本篇为【死磕 Spring】系列博客的第一篇博文,主要介绍 ...

chenssy
2018/09/02
0
0
Spring 面试问题 TOP 50

Spring 面试问题 TOP 50 Spring Framework 现在几乎已成为 Java Web 开发的标配框架。那么,作为 Java 程序员,你对 Spring 的主要技术点又掌握了多少呢?不妨用本文的问题来检测一下。 本文...

静默虚空
2018/08/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Vue.js开发环境搭建说明(mac)

vue开发环境搭建(mac) 投影放大:cmd + + 安装Node 下载Node 官网下载 https://nodejs.org/en/download/ 安装Node 双击安装包,选择安装目录,比如: /usr/local/bin 安装成功后最好记录一...

Danni3
11分钟前
1
0
Qt编写自定义控件3-速度仪表盘

前言 速度仪表盘,写作之初的本意是用来展示当前测试的网速用的,三色圆环+数码管显示当前速度,Qt自带了数码管控件QLCDNumber,直接集成即可,同时还带有动画功能,其实也可以用在汽车+工业...

飞扬青云
16分钟前
0
0
【论文阅读】Image Super-Resolution via Deep Recursive Residual Network

题目:通过深度递归残差网络实现图像的超分辨率 摘要: 近年来,基于卷积神经网络的模型在单张图像的超分辨率上已经取得了巨大的成功。由于深度网络的强大,这些CNN模型学习了从低分辨率输入...

云烟成雨forever
18分钟前
0
0
为什么强烈建议大家使用枚举来实现单例

关于单例模式,我的博客中有很多文章介绍过。作为23种设计模式中最为常用的设计模式,单例模式并没有想象的那么简单。因为在设计单例的时候要考虑很多问题,比如线程安全问题、序列化对单例的...

群星纪元
37分钟前
11
0
Confluence 6 超过当前许可证期限进行升级

这个页面将会对你在进行 Confluence 升级的时候超过了当前许可证的期限进行升级的情况。 许可证警告 在升级的过程中,你将会在 Confluence 的应用程序日志(log file)中看到类似下面的错误提...

honeymoose
50分钟前
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部