菜鸟学习Spring——60s让你学会动态代理原理
一、为什么要使用动态代理
当一个对象或多个对象实现了N中方法的时候,由于业务需求需要把这个对象和多个对象的N个方法加入一个共同的方法,比如把所有对象的所有方法加入事务这个时候有三种方法:
方法一:一个一个对象一个一个方法去加,很显然这个方法是一个比较笨的方法。
方法二:加一个静态代理对象将这个静态代理对象实现要加事务对象的接口。然后在静态代理对象里面每个方法里面加上事务。
方法三:使用动态代理对象,进行动态的加载事务。
使用动态代理是为了让对象实现了开闭原则,对扩展开放,而对修改关闭。Spring的AOP其实就是用了动态代理+IoC容器实现的
二、代码实现。UserManger.java接口
package com.tgb.spring; public interface UserManager { public void addUser(String username,String password); public void delUser(int userId); public String findUserById(int userId); public void modifyUser(int userId,String username,String password); }方法一 常规的做法:
UserMangerImpl.Java
package com.tgb.spring; public class UserManagerImpl implements UserManager { public void addUser(String username, String password) {
checkSecurity();
System.out.println("UserManager.addUser"); } public void delUser(int userId) {
checkSecurity();
System.out.println("UserManager.delUser"); } public String findUserById(int userId) {
checkSecurity();
System.out.println("UserManager.findUserById");
return "张三";
} public void modifyUser(int userId, String username, String password) {
checkSecurity();
System.out.println("UserManager.modifyUser"); } private void checkSecurity(){
System.out.println("checkSecurity"); }
}Client.java
package com.tgb.spring; public class Client { /**
* @param args
*/
public static void main(String[] args) {
UserManager userManager=new UserManagerImpl();
userManager.addUser("11", "1231");
} }方法二 静态代理:
UserManagerImpl.java
package com.tgb.spring; public class UserManagerImpl implements UserManager { public void addUser(String username, String password) {
//checkSecurity();
System.out.println("UserManager.addUser"); } public void delUser(int userId) {
//checkSecurity();
System.out.println("UserManager.delUser"); } public String findUserById(int userId) {
//checkSecurity();
System.out.println("UserManager.findUserById");
return "张三";
} public void modifyUser(int userId, String username, String password) {
//checkSecurity();
System.out.println("UserManager.modifyUser"); } // private void checkSecurity(){
// System.out.println("checkSecurity");
//
// } }UserManagerImplProxy.java
package com.tgb.spring; public class UserManagerImplProxy implements UserManager { private UserManager userManager; public UserManagerImplProxy(UserManager userManager){
this.userManager=userManager;
} public void addUser(String username, String password) {
// TODO Auto-generated method stub
checkSecurity();
userManager.addUser(username, password);
} public void delUser(int userId) {
// TODO Auto-generated method stub
checkSecurity();
userManager.delUser(userId);
} public String findUserById(int userId) {
// TODO Auto-generated method stub
checkSecurity(); return userManager.findUserById(userId);
} public void modifyUser(int userId, String username, String password) {
// TODO Auto-generated method stub
checkSecurity();
userManager.modifyUser(userId, username, password); } private void checkSecurity(){
System.out.println("checkSecurity"); }
}Client.java
package com.tgb.spring; public class Client { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
UserManagerImpl uesrMangerImpl=new UserManagerImpl();
UserManager userManager=new UserManagerImplProxy(uesrMangerImpl); userManager.addUser("11", "1231");
} }方法三:动态代理
UserManagerImpl.java与方法二的UserManagerImpl.java一样把UserManagerImplProxy.java删除
新添一个类:
SecurityHandler.java
package com.tgb.spring; import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class SecurityHandler implements InvocationHandler { private Object targetObject; public Object createProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(),
this);
} public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
checkSecurity();
//调用目标方法
Object ret=method.invoke(targetObject, args);
return ret;
} private void checkSecurity(){
System.out.println("checkSecurity"); } }Client.java
package com.tgb.spring; public class Client { public static void main(String[] args) {
SecurityHandler handler=new SecurityHandler();
UserManager userManager=(UserManager)handler.createProxyInstance(new UserManagerImpl());
userManager.addUser("zha", "123");
}
}三种方法的效果是一样的如图:
三、总结。
动态代理的利用给我们编码带来了很大的便利,解决了动态为对象提供服务的方案。动态代理+IoC容器的结合让我们对系统提供服务更加的方便了这样我们也就实现了开闭原则。这样也就能实现了对象想要的时候就有不用的时候就撤出全心全意为开发者服务。
菜鸟学习Spring——60s让你学会动态代理原理的更多相关文章
- 菜鸟学习Spring——60s配置XML方法实现简单AOP
一.概述. 上一篇博客讲述了用注解的形式实现AOP现在讲述另外一种AOP实现的方式利用XML来实现AOP. 二.代码演示. 准备工作参照上一篇博客<菜鸟学习Spring--60s使用annota ...
- 菜鸟学习Spring——60s使用annotation实现简单AOP
一.概述. AOP大家都知道切面编程,在Spring中annotation可以实现简单的AOP列子.下面还未大家介绍几个概念: Aspect 对横切性关注点的模块化. Advice 对横切性关注点的具 ...
- 菜鸟学习Spring——60s学会Spring与Hibernate的集成
一.概述. Spring与Hibernate的集成在企业应用中是很常用的做法通过Spring和Hibernate的结合能提高我们代码的灵活性和开发效率,下面我就一步一步的给大家讲述Spring如何和H ...
- 菜鸟学习Spring——60s利用JoinPoint获取参数的值和方法名称
一.概述 AOP的实现方法在上两篇博客中已经用了两种方法来实现现在的问题来了虽然我们利用AOP,那么客户端如何信息传递?利用JoinPoint接口来实现客户端给具体实现类的传递参数. 二.代码演示. ...
- 菜鸟学习Spring——60s利用JoinPoint获取參数的值和方法名称
一.概述 AOP的实现方法在上两篇博客中已经用了两种方法来实现如今的问题来了尽管我们利用AOP,那么client怎样信息传递?利用JoinPoint接口来实现client给详细实现类的传递參数. 二. ...
- Spring AOP动态代理原理与实现方式
AOP:面向切面.面向方面.面向接口是一种横切技术横切技术运用:1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物 2.日志处理:3.安全验证 ...
- Spring @Trasactionl 失效, JDK,CGLIB动态代理
@Transaction: http://blog.csdn.net/bao19901210/article/details/41724355 Spring上下文: http://blog.csd ...
- 动态代理 原理简析(java. 动态编译,动态代理)
动态代理: 1.动态编译 JavaCompiler.CompilationTask 动态编译想理解自己查API文档 2.反射被代理类 主要使用Method.invoke(Object o,Object ...
- 设计模式 - 动态代理原理及模仿JDK Proxy 写一个属于自己的动态代理
本篇文章代码内容较多,讲的可能会有些粗糙,大家可以选择性阅读. 本篇文章的目的是简单的分析动态代理的原理及模仿JDK Proxy手写一个动态代理以及对几种代理做一个总结. 对于代理模式的介绍和讲解,网 ...
随机推荐
- [Java] 我的Coding Style 总结
1. 缩进 采用4个空格的缩进方式 2. tab 不采用"hard" tab. 需要更改编辑器的默认配置.将tab值改成4个空格. 3. 换行 3.1 一行不超过75个字符 3.2 ...
- X86 架构和 ARM 架构
1.关于x86架构 X86是一个intel通用计算机系列的标准编号缩写,也标识一套通用的计算机指令集合,X86是由Intel推出的一种复杂指令集,用于控制芯片的运行的程序,现在X86已经广泛运用到了家 ...
- BZOJ3613 南园满地堆轻絮-二分法
http://www.lydsy.com/JudgeOnline/problem.php?id=3613 //话说BZOJ终于修好了... Description 小 Z 是 ZRP(Zombies' ...
- 由多次使用Statement实例引起的Result set already closed异常的解决方案
在不同版本的Weblogic平台上迁移应用,产生了很严重的JDBC驱动版本不兼容的问题. 但是归根究底是代码的问题,废话少说,上代码示例. ..... //以下是问题代码 ResultSet rs=n ...
- 学习总结 java 异常
package com.hanqi.ec; public class Test1 { public static void main(String[] args) { int a = 10 , b = ...
- Cnetos7下,已经能访问tomcat
进入/usr/local/apache-tomcat-8.0.24/bin 中 执行:./startup.sh开启tomcat 再执行如下 systemctl stop firewalld.servi ...
- 华为OJ平台——字符串通配符
题目描述: 在计算机中,通配符一种特殊语法,广泛应用于文件搜索.数据库.正则表达式等领域.现要求各位实现字符串通配符的算法.要求:实现如下2个通配符: *:匹配0个或以上的字符(字符由英文字母和数字0 ...
- 《Ossim应用指南》入门篇
Ossim应用入门 --在<OSSIM在企业网络管理中的应用>http://chenguang.blog.51cto.com/350944/802007 这篇文章发布之后,很多同行对oss ...
- js 打开PDF
用插件打开PDF的一个超连接 但是谷歌了很久 ,发现了一个很好的方法 就是借google 来打开一个PDF ,而不下载PDF: _yourID.setAttribute('onclick'," ...
- use python get information from one page
#!/usr/bin/python read = file('thread-1554-1-1.html','r') wr = file('list','w') while 1: line=read.r ...