IoC in Spring
写两个关于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的更多相关文章
- Spring源码-IOC部分-Spring是如何解决Bean循环依赖的【6】
实验环境:spring-framework-5.0.2.jdk8.gradle4.3.1 Spring源码-IOC部分-容器简介[1] Spring源码-IOC部分-容器初始化过程[2] Spring ...
- Spring学习3—控制反转(IOC)Spring依赖注入(DI)和控制反转(IOC)
一.思想理解 Spring 能有效地组织J2EE应用各层的对象.不管是控制层的Action对象,还是业务层的Service对象,还是持久层的DAO对象,都可在Spring的 管理下有机地协调.运行.S ...
- spring ioc 原理 spring aop原理
大家一直都说spring的IOC如何如何的强大,其实我倒觉得不是IOC如何的强大,说白了IOC其实也非常的简单.我们先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对 ...
- AS3 IOC框架Spring Actionscript 的使用总结
Spring Actionscript 是众多围绕依赖注入提供解决方案的Flex控制反转框架之一 AS3 下经典的IOC框架有Spring ActionScript.Parsley.Flicc和Swi ...
- Spring IOC和Spring AOP的实现原理(源码主线流程)
写在前面 正本文参考了<spring技术内幕>和spring 4.0.5源码.本文只描述原理流程的主线部分,其他比如验证,缓存什么可以具体参考源码理解. Spring IOC 一.容器初始 ...
- IoC之Spring.Net在Mvc项目中的使用
MVC中使用Spring.net 前面学习了使用Autofac来实现控制反转,这里简单记录Spring.Net实现IoC和DI的步骤 第一步:安装如下Nuget包 (Spring.Web.Mvc) i ...
- spring揭密学习笔记(3)-spring ioc容器:Spring的IoC容器之BeanFactory
1. Spring的IoC容器和IoC Service Provider的关系 Spring的IoC容器和IoC Service Provider所提供的服务之间存在一定的交集,二者的关系如图4-1所 ...
- 关于 IOC和spring基本配置详解
Spring 中的两个概念 IOC控制反转(也叫依赖注入DI): AOP面向切面编程: 控制反转:当某个java对象需要(依赖)另一个java对象是,不是直接创建依赖对象,而是由实现IOC的容器来创建 ...
- .net IoC 之 Spring.Net 适合刚开始使用
Spring.Net包括控制反转(IoC) 和面向切面(AOP),这篇文章主要说下IoC方面的入门. 一.首先建立一个MVC项目名称叫SpringDemo,然后用NuGet下载spring(我用的是S ...
随机推荐
- ssh 自动登录
工作中经常会有这样的需求场景,因为要在其它电脑上做操作, 需要从PC A ssh 到 PC B,PC A 可能是自己的工作机,PC B 可能是服务器.一般会使用 SSH 登录到 server 上再进行 ...
- OR导致笛卡尔积
近期监控数据库,发现以下语句跑得很慢,原来运行计划走了导致笛卡尔积,来看以下语句: SQL> explain plan for 2 SELECT COUNT(*) 3 FROM "GD ...
- Front End Books
Front End Books 记录和推荐一些认为还不错的前端方面的书籍.列入标准: 看过,并觉得值得推荐给大家的. 正在看的,已经觉得不错的,或者听闻别人说不错的. 打算看的,经多人推荐,一致认为必 ...
- 移动端App混合开发问题 汇总
1.IOS系统,双击页面,页面会向上移动一节,无法滑动复原. //阻止用户双击放大 var agent = navigator.userAgent.toLowerCase(); //检测是否是ios ...
- PDF解决方案(1)--文件上传
相关专题链接 PDF解决方案(1)--文件上传 PDF解决方案(2)--文件转PDF PDF解决方案(3)--PDF转SWF PDF解决方案(4)--在线浏览 前言:最近参与了一个项目,客户要求把系统 ...
- FPGA 设计怎样进行面积优化(逻辑资源占用量优化)
FPGA面积优化 1 对于速度要求不是非常高的情况下,我们能够把流水线设计成迭代的形式,从而反复利用FPGA功能同样的资源. 2 对于控制逻辑小于共享逻辑时,控制逻辑资源能够用来复用,比如FIR滤波器 ...
- 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 ...
- springmvc3.1.1+hibernate4
上篇介绍了基本的配置,这篇着重介绍与hibernate4整合. 1.web.xml文件中加入spring-hibernate的配置.新的web.xml文件内容如下: <?xml version= ...
- iOS基础 - 相片浏览器
一.需求分析 点击照片从当前照片位置动画弹出新的视图控制器显示选中的照片,新的视图控制器为全屏显示,背景为黑色,再次点击照片动画缩小至当前选中的照片位置,双击放大照片,如果已经放大则缩小,在新的视图控 ...
- iOS基础 - 触摸事件&手势识别
================================================================== 一.触摸事件&手势识别 1> 4个触摸事件,针对视图 ...