写两个关于Spring中使用IoC的小例子,一个是半动态创建Bean,另一个是全动态创建Bean,它们适合不同的应用场景。

  一、半动态:在一个实际项目中遇到过这样的问题,项目组开发的某个系统具备在LED屏上显示信息的功能。不同客户那里的LED屏各不相同,主要区别是驱动卡和显示格式。如果每次换LED屏时都是靠程序员去替换不同实现的代码,成本可想而知。那么,在不修改既有代码(甚至是不用编译既有工程)的情况下,怎样才能让系统的这个功能适应变化呢?

  首先抽象出一个接口,代表向LED屏打印的功能。

package com.mmh.printer;

public interface LEDPrinter {

    public void print(String content);
}

  然后根据不同品牌的LED屏,编写具体的打印功能。

package com.mmh.printer;

public class Brand1LEDPrinter implements LEDPrinter {

    @Override
public void print(String content) {
// 模拟不同品牌的LED显示屏操作
System.out.println("这是品牌1的LED显示内容: " + content);
}
}

  紧接着编写一个辅助类,客户端程序通过它实现LED屏的打印功能。

package com.mmh.printer;

public class LEDPrintHelper {

    private LEDPrinter printer;

    public void setPrinter(LEDPrinter printer) {
this.printer = printer;
} public void print(String content) {
printer.print(content);
}
}

  最后实现一个客户端调用的演示程序。

package com.mmh.main;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mmh.printer.LEDPrintHelper; public class Application { public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext(
"appContext.xml"); LEDPrintHelper ledPrintHelper = (LEDPrintHelper) context.getBean("LEDPrintHelper");
ledPrintHelper.print("业务层产生的数据");
}
}

  在LED屏更换时,以上的代码,不管是调用方的还是被调用方的,都不需要做任何的修改。假设现在客户使用的是Brand2品牌LED屏,那么程序员只需要针对这种屏编写具体操作即可。

package com.mmh.printer;

public class Brand2LEDPrinter implements LEDPrinter {

    @Override
public void print(String content) {
// 模拟不同品牌的LED显示屏操作
System.out.println("这是品牌2的LED显示内容: " + content);
}
}

这个具体实现类完全可以封装到一个单独的jar中,那么以前的既有代码对于现在的开发人员可以完全透明。

  应对变化的功能是靠Spring的IoC来实现的。

<?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"> <bean id="LEDPrintHelper" class="com.mmh.printer.LEDPrintHelper">
<property name="printer" ref="Brand1LEDPrinter" />
</bean> <bean id="Brand1LEDPrinter" class="com.mmh.printer.Brand1LEDPrinter" /> <bean id="Brand2LEDPrinter" class="com.mmh.printer.Brand2LEDPrinter" /> </beans>

该配置文件定义了三个Bean,LEDPrintHelper是调用程序的接口,Brand1LEDPrinter和Brand2LEDPrinter分别代表了两种屏的具体操作。通过属性注入的方式,开发人员手动修改(这就是半动态的意思)LEDPrintHelper的printer属性值,从而更改LED屏的具体操作。

  二、全动态:在实际项目中还遇到过这样的问题,不同类型用户的登录实现方式是不同的,并且在系统的使用过程中用户的类型会不断增加。那么,在不修改既有代码(甚至是不用编译既有工程)的情况下,怎样才能让系统的这个功能适应变化呢?

  首先抽象一个接口,代表用户登录功能。

package com.mmh.login;

public interface UserLogin {
public boolean login(String username, String password);
}

  然后实现不同类型用户的登录过程。

package com.mmh.login;

public class UserALogin implements UserLogin {

    @Override
public boolean login(String username, String password) {
System.out.println("根据UserA的业务逻辑处理登录过程"); return true;
}
}
package com.mmh.login;

public class UserBLogin implements UserLogin {

    @Override
public boolean login(String username, String password) {
System.out.println("根据UserB的业务逻辑处理登录过程"); return true;
}
}

  紧接着开放给客户调用端一个统一的接口。这个接口在实际系统中经常会被实现为一个web service。

package com.mmh.login;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class UserLoginService { private ApplicationContext context = new ClassPathXmlApplicationContext(
"appContext.xml"); public boolean login(String username, String password, String logintype) {
UserLogin userLogin = (UserLogin) context.getBean(logintype); return userLogin.login(username, password);
}
}

  最后还是编写一个客户调用的演示。

package com.mmh.main;

import com.mmh.login.UserLoginService;

public class Application {

    public static void main(String[] args) {
UserLoginService service = new UserLoginService(); service.login("userA", "123456", "UserALogin"); service.login("userB", "123456", "UserBLogin");
}
}

  从上面的代码可以看到,不同的用户可以调用相同的接口进行不同的登录操作,被调用程序根据用户输入的参数自动匹配登录过程(这就是全动态的意思)。并且当系统增加用户类型时,既有代码不需要修改。应对变化的功能仍是靠Spring的IoC来实现的。

<?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"> <bean id="UserALogin" class="com.mmh.login.UserALogin" /> <bean id="UserBLogin" class="com.mmh.login.UserBLogin" /> </beans>

IoC in Spring的更多相关文章

  1. Spring源码-IOC部分-Spring是如何解决Bean循环依赖的【6】

    实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...

  2. Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)

    一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...

  3. spring ioc 原理 spring aop原理

    大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单.我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对 ...

  4. AS3 IOC框架Spring Actionscript 的使用总结

    Spring Actionscript 是众多围绕依赖注入提供解决方案的Flex控制反转框架之一 AS3 下经典的IOC框架有Spring ActionScript.Parsley.Flicc和Swi ...

  5. Spring IOC和Spring AOP的实现原理(源码主线流程)

    写在前面 正本文参考了<spring技术内幕>和spring 4.0.5源码.本文只描述原理流程的主线部分,其他比如验证,缓存什么可以具体参考源码理解. Spring IOC 一.容器初始 ...

  6. IoC之Spring.Net在Mvc项目中的使用

    MVC中使用Spring.net 前面学习了使用Autofac来实现控制反转,这里简单记录Spring.Net实现IoC和DI的步骤 第一步:安装如下Nuget包 (Spring.Web.Mvc) i ...

  7. spring揭密学习笔记(3)-spring ioc容器:Spring的IoC容器之BeanFactory

    1. Spring的IoC容器和IoC Service Provider的关系 Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所 ...

  8. 关于 IOC和spring基本配置详解

    Spring 中的两个概念 IOC控制反转(也叫依赖注入DI): AOP面向切面编程: 控制反转:当某个java对象需要(依赖)另一个java对象是,不是直接创建依赖对象,而是由实现IOC的容器来创建 ...

  9. .net IoC 之 Spring.Net 适合刚开始使用

    Spring.Net包括控制反转(IoC) 和面向切面(AOP),这篇文章主要说下IoC方面的入门. 一.首先建立一个MVC项目名称叫SpringDemo,然后用NuGet下载spring(我用的是S ...

随机推荐

  1. ssh 自动登录

    工作中经常会有这样的需求场景,因为要在其它电脑上做操作, 需要从PC A ssh 到 PC B,PC A 可能是自己的工作机,PC B 可能是服务器.一般会使用 SSH 登录到 server 上再进行 ...

  2. OR导致笛卡尔积

    近期监控数据库,发现以下语句跑得很慢,原来运行计划走了导致笛卡尔积,来看以下语句: SQL> explain plan for 2 SELECT COUNT(*) 3 FROM "GD ...

  3. Front End Books

    Front End Books 记录和推荐一些认为还不错的前端方面的书籍.列入标准: 看过,并觉得值得推荐给大家的. 正在看的,已经觉得不错的,或者听闻别人说不错的. 打算看的,经多人推荐,一致认为必 ...

  4. 移动端App混合开发问题 汇总

    1.IOS系统,双击页面,页面会向上移动一节,无法滑动复原. //阻止用户双击放大 var agent = navigator.userAgent.toLowerCase(); //检测是否是ios ...

  5. PDF解决方案(1)--文件上传

    相关专题链接 PDF解决方案(1)--文件上传 PDF解决方案(2)--文件转PDF PDF解决方案(3)--PDF转SWF PDF解决方案(4)--在线浏览 前言:最近参与了一个项目,客户要求把系统 ...

  6. FPGA 设计怎样进行面积优化(逻辑资源占用量优化)

    FPGA面积优化 1 对于速度要求不是非常高的情况下,我们能够把流水线设计成迭代的形式,从而反复利用FPGA功能同样的资源. 2 对于控制逻辑小于共享逻辑时,控制逻辑资源能够用来复用,比如FIR滤波器 ...

  7. Using Ninject in a Web Application

    http://aidenweb.co.uk/?p=15 Using Ninject in a Web Application I have been meaning to look at Ninjec ...

  8. springmvc3.1.1+hibernate4

    上篇介绍了基本的配置,这篇着重介绍与hibernate4整合. 1.web.xml文件中加入spring-hibernate的配置.新的web.xml文件内容如下: <?xml version= ...

  9. iOS基础 - 相片浏览器

    一.需求分析 点击照片从当前照片位置动画弹出新的视图控制器显示选中的照片,新的视图控制器为全屏显示,背景为黑色,再次点击照片动画缩小至当前选中的照片位置,双击放大照片,如果已经放大则缩小,在新的视图控 ...

  10. iOS基础 - 触摸事件&手势识别

    ================================================================== 一.触摸事件&手势识别 1> 4个触摸事件,针对视图 ...