深入浅出Spring(四) Spring实例分析
上次的博文中 深入浅出Spring(二) IoC详解 和 深入浅出Spring(三) AOP详解中,我们分别介绍了一下Spring框架的两个核心一个是IoC,一个是AOP。接下来我们来做一个Spring的实例。
为了更好的讲解Spring的相关内容,这次的博文会针对一个【添加用户】的实例,进行逐步的解剖和优化,再此过程中,细节内容大家不需要考虑,只需要加深对Spring的理解即可。
1、实例一
首先,我们来看一个没有使用任何Spring框架内容,比较单纯的添加用户的实例。先看一下相关的类图和实现代码,具体如下:
public class User {
private String username;
private String password; public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
} public interface UserDao { public void addUser(User user);
} public class UserDao4OracleImpl implements UserDao { @Override
public void addUser(User user) {
System.out.println("UserDao4OracleImpl.addUser() , username="+user.getUsername());
}
} public class UserDao4MySqlImpl implements UserDao { @Override
public void addUser(User user) {
System.out.println("UserDao4MySqlImpl.addUser() , username="+user.getUsername());
}
} public interface UserManager {
public void addUser(User user);
} public class UserManagerImpl implements UserManager {
@Override
public void addUser(User user) {
UserDao userDao = new UserDao4MySqlImpl();
userDao.addUser(user);
}
}
public class Client {
public static void main(String[] args) { User user = new User();
user.setUsername("张三");
user.setPassword("123456"); UserManager userManager = new UserManagerImpl();
userManager.addUser(user); }
}
分析上面的类图和代码中,我们可以很明显的看出:在UserManagerImpl类的方法addUser中,UserManagerImpl调用了UserDao及其具体的实现类UserDao4MySqlImpl,这就不符合IoC模式中,将接口的具体实现类的控制权从调用类中分离转交给第三方决定的相关思想,所以我们需要在这里进行修改。(参考我们之前的IoC文章)。
2、实例二
针对实例一中不符合IoC思想的部分,我们进行相关修改,具体修改之后的相关类图和代码如下:
public class UserManagerImpl implements UserManager {
private UserDao userDao;
public UserManagerImpl (UserDao userDao){
this.UserDao = userDao;
} @Override
public void addUser(User user) {
this.userDao.addUser(user);
}
} public class Client {
public static void main(String[] args) { User user = new User();
user.setUsername("张三");
user.setPassword("123456"); UserDao userDao = new UserDao4MySqlImpl(); UserManager userManager = new UserManagerImpl(userDao);
userManager.addUser(user); }
}
分析上面修改之后的类图和代码,我们发现,虽然我们将UserDao的控制权交给了Client,但在Client中却存在对UserDao及其相关实现类的依赖,这样对于Client来讲,Client类与UserDao类之间的耦合性反而不如我们之前写的代码低。如何优化呢?我们这里就不做太多的思考,直接使用Spring的相关内容即可。
3、实例三
对于实例二的问题,先来看一下我们使用Spring框架修改之后的相关类图,具体如下:
看完上面类图之后,我们对比于第一张类图,可以看出:类与类之间的相互依赖更少,这样的结构能够使我们的代码耦合性更低。但这张类图的代码究竟是如何实现的呢?接下来,重点看一下我们需要修改的目标Client类的相关代码,具体如下:
public class Client { public static void main(String[] args) { User user = new User();
user.setUsername("张三");
user.setPassword("123456"); BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
UserManager userManager = (UserManager)factory.getBean("userManager");
userManager.addUser(user);
}
}
通过对比上面的代码和我们第二个实例中关于Client类的代码可以看出,上面的代码用到了一个BeanFactory类和XML文件,这就是Spring框架使用的核心类和实现方式。了解了两者的区别,我们再看一下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:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd"> <bean id="userDao4MySqlImpl" class="com.zs.spring.dao.UserDao4MySqlImpl"/> <bean id="userManager" class="com.zs.spring.manager.UserManagerImpl">
<property name="userDao" ref="userDao4MySqlImpl"/>
</bean>
</beans>
关于这个XML文件,我会在接下来的文章中重点进行讲解,这里只告诉大家,它的作用就是将对象之间的依赖关系交由Spring容器进行控制,避免硬编码所造成的过度程序耦合。即相当于下面的两句代码:
UserManager userManager = new UserManagerImpl(userDao);
UserDao userDao = new UserDao4MySqlImpl();
4、总结
对比上面的三张类图,我们可以看到,使用Spring框架, 将对象之间的依赖关系交由Spring容器进行控制,通过使用XML文件将对象之间的调用关系从代码中分离,避免硬编码所造成的过度程序耦合,这正是Spring框架实现解耦的核心思想。
到此为止,关于Spring的实例就讲解完毕了,讲解的不是很细,大家只需要对Spring框架有一个初步的认识即可。至于Spring运行过程中的具体实现,我会在下次的博文中继续讲解,以便加深大家对Spring的理解。
给大家提供一个博文配套的参考实例代码下载地址:
深入浅出Spring(四) Spring实例分析的更多相关文章
- 深入浅出JMS(四)--Spring和ActiveMQ整合的完整实例
第一篇博文深入浅出JMS(一)–JMS基本概念,我们介绍了JMS的两种消息模型:点对点和发布订阅模型,以及消息被消费的两个方式:同步和异步,JMS编程模型的对象,最后说了JMS的优点. 第二篇博文深入 ...
- 精尽Spring MVC源码分析 - HandlerMapping 组件(四)之 AbstractUrlHandlerMapping
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- Spring Ioc源码分析系列--容器实例化Bean的四种方法
Spring Ioc源码分析系列--实例化Bean的几种方法 前言 前面的文章Spring Ioc源码分析系列--Bean实例化过程(二)在讲解到bean真正通过那些方式实例化出来的时候,并没有继续分 ...
- 精尽Spring MVC源码分析 - HandlerAdapter 组件(四)之 HandlerMethodReturnValueHandler
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
- Spring Security 源码分析(四):Spring Social实现微信社交登录
社交登录又称作社会化登录(Social Login),是指网站的用户可以使用腾讯QQ.人人网.开心网.新浪微博.搜狐微博.腾讯微博.淘宝.豆瓣.MSN.Google等社会化媒体账号登录该网站. 前言 ...
- Spring学习十四----------Spring AOP实例
© 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...
- Spring IOC 源码分析
Spring 最重要的概念是 IOC 和 AOP,本篇文章其实就是要带领大家来分析下 Spring 的 IOC 容器.既然大家平时都要用到 Spring,怎么可以不好好了解 Spring 呢?阅读本文 ...
- spring+mybatis结合实例
1.通过上两篇文章的学习,大致了解了spring和mybatis的架构和使用原理,下面这篇文章就将给出两者结合的一个小实例,通过该实例进一步探索这两个框架的魅力,工程所需要的所有jar包都在链接:ht ...
- Spring AOP源码分析--代理方式的选择
能坚持别人不能坚持的,才能拥有别人未曾拥有的.关注编程大道公众号,让我们一同坚持心中所想,一起成长!! 年前写了一个面试突击系列的文章,目前只有redis相关的.在这个系列里,我整理了一些面试题与大家 ...
- 精尽Spring MVC源码分析 - HandlerMapping 组件(一)之 AbstractHandlerMapping
该系列文档是本人在学习 Spring MVC 的源码过程中总结下来的,可能对读者不太友好,请结合我的源码注释 Spring MVC 源码分析 GitHub 地址 进行阅读 Spring 版本:5.2. ...
随机推荐
- 【解题报告】[动态规划] CodingTrip - 携程编程大赛 (预赛第一场)- 聪明的猴子
原题: 聪明的猴子 Time Limit : 2000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other) Problem D ...
- 剑指offer—第三章高质量代码(o(1)时间删除链表节点)
题目:给定单向链表的头指针和一个节点指针,定义一个函数在O(1)时间删除该节点,链表节点与函数的定义如下:struct ListNode{int m_nValue;ListNode* m_pValue ...
- APP打包上线应注意的问题!
咱们只谈技术不谈业务!关系到怎么推广怎么让软件发扬光大,其实归根结底这都和公司的现状和产品经理有直接的联系,与我们程序员关系不太密切. 我总结的上线项目和我做的项目以及公司外包过来的项目升级再次发 ...
- Android的IPC机制(一)——AIDL的使用
综述 IPC(interprocess communication)是指进程间通信,也就是在两个进程间进行数据交互.不同的操作系统都有他们自己的一套IPC机制.例如在Linux操作系统中可以通过管道. ...
- Spring aop 实现异常拦截
使用aop异常挂载功能可以统一处理方法抛出的异常,减少很多重复代码,实现如下: 1.实现ThrowAdvice public class ExceptionHandler implements Thr ...
- EL表达式(胖先生版)
EL表达式没有指定范围,从最小范围开始 <% pageContext.setAttribute("shxt", "java web"); request. ...
- Go 语言做的几个验证码
1.http://www.oschina.net/code/snippet_173630_12006 : 效果: 源代码: 1: package main 2: 3: import ( 4: cra ...
- 发现第三方资源,chrome控制台
for(var i=0,tags=document.querySelectorAll('iframe[src],frame[src],script[src],link[rel=stylesheet], ...
- js正则表达式中=s.g表示什么意思
//g是全局匹配//中间的内容表示:匹配以=开关,后面是0或多个空格,然后是双引号括起来的任意字符,比如:= "any symble" 匹配 = " asfjaskldf ...
- coroutine in c 备忘
coroutine: stackless和stackful jmp 基于switch的trick: http://www.chiark.greenend.org.uk/~sgtatham/corout ...