菜鸟学习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手写一个动态代理以及对几种代理做一个总结. 对于代理模式的介绍和讲解,网 ...
随机推荐
- Hibernate和JDBC、EJB比较
参考:http://m.blog.csdn.net/article/details?id=7228061 一.Hibernate是JDBC的轻量级的对象封装,它是一个独立的对象持久层框架,和App S ...
- 腾讯校招技术岗面试经历及总结(已发offer)
关于笔试:只要前期复习到位,笔试还是很好过的,但是当然 分数 越高越好,否则后面会被面试官鄙视的.题目可能难度较大,但是要把会做的 都做 对,如果时间比较紧可以适度放弃部分不会的题目. 关于面试: 温 ...
- C/C++程序基础
作为一名cocos2dx前端(客户端)开发,知乎上看到一片文章,怎么看待做手游cocos前端开发,lua用的多,c++用的少面试会被鄙视? 为了不被鄙视,所以要学好C++,多做积累.本文主要是根据&l ...
- Solum入门知识(编辑中)
概要 参考:https://wiki.openstack.org/wiki/Solum An OpenStack project designed to make cloud services eas ...
- 【练习】如何显示本地主机上的MySQL客户机版本
在终端窗口以oracle用户身份登录 [root@enmo ~]# su - oracle [oracle@enmo ~]$ mysql -V mysql Ver , for Linux (x86_6 ...
- 跟我学 NHibernate (一)
NHibernate 是一个强大的 ORM 框架,本博文主要就 NHibernate 的使用方法及语法做一些简单的介绍. 1.NHibernate 语法 新建一个类,命名为: QueryCrit ...
- noip2009 潜伏者
P1071 潜伏者 827通过 2.2K提交 题目提供者洛谷OnlineJudge 标签字符串模拟2009NOIp提高组 难度普及/提高- 提交该题 讨论 题解 记录 题目描述 R 国和 S 国正 ...
- 常用思科设备图标(JPG+矢量图)
常用思科设备图标 在制作网络拓扑图示时我们利用MS Visio或亿图图示等制图软件自带的网络设备绘制拓扑图感觉提供的设备图标非常有限,往往不满足我们的要求,这时就常需要找一些思科的设备图标,在网上到处 ...
- keepalive实现web服务器active/passive
https://github.com/acassen/keepalived/blob/v1.2.13/doc/keepalived.conf.SYNOPSIS http://ngyuki.hatena ...
- angular.extend(dst, src)对象拓展
angular.extend(dst, src) 作用:对象的拓展 参数: dst:拓展的对象 src:源对象 返回值:拓展的对象 var dst = {name: 'xxx', country: ...