一、为什么要使用动态代理

        当一个对象或多个对象实现了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让你学会动态代理原理的更多相关文章

  1. 菜鸟学习Spring——60s配置XML方法实现简单AOP

    一.概述. 上一篇博客讲述了用注解的形式实现AOP现在讲述另外一种AOP实现的方式利用XML来实现AOP. 二.代码演示. 准备工作参照上一篇博客<菜鸟学习Spring--60s使用annota ...

  2. 菜鸟学习Spring——60s使用annotation实现简单AOP

    一.概述. AOP大家都知道切面编程,在Spring中annotation可以实现简单的AOP列子.下面还未大家介绍几个概念: Aspect 对横切性关注点的模块化. Advice 对横切性关注点的具 ...

  3. 菜鸟学习Spring——60s学会Spring与Hibernate的集成

    一.概述. Spring与Hibernate的集成在企业应用中是很常用的做法通过Spring和Hibernate的结合能提高我们代码的灵活性和开发效率,下面我就一步一步的给大家讲述Spring如何和H ...

  4. 菜鸟学习Spring——60s利用JoinPoint获取参数的值和方法名称

    一.概述 AOP的实现方法在上两篇博客中已经用了两种方法来实现现在的问题来了虽然我们利用AOP,那么客户端如何信息传递?利用JoinPoint接口来实现客户端给具体实现类的传递参数. 二.代码演示. ...

  5. 菜鸟学习Spring——60s利用JoinPoint获取參数的值和方法名称

    一.概述 AOP的实现方法在上两篇博客中已经用了两种方法来实现如今的问题来了尽管我们利用AOP,那么client怎样信息传递?利用JoinPoint接口来实现client给详细实现类的传递參数. 二. ...

  6. Spring AOP动态代理原理与实现方式

    AOP:面向切面.面向方面.面向接口是一种横切技术横切技术运用:1.事务管理: (1)数据库事务:(2)编程事务(3)声明事物:Spring AOP-->声明事物   2.日志处理:3.安全验证 ...

  7. Spring @Trasactionl 失效, JDK,CGLIB动态代理

    @Transaction:  http://blog.csdn.net/bao19901210/article/details/41724355 Spring上下文:  http://blog.csd ...

  8. 动态代理 原理简析(java. 动态编译,动态代理)

    动态代理: 1.动态编译 JavaCompiler.CompilationTask 动态编译想理解自己查API文档 2.反射被代理类 主要使用Method.invoke(Object o,Object ...

  9. 设计模式 - 动态代理原理及模仿JDK Proxy 写一个属于自己的动态代理

    本篇文章代码内容较多,讲的可能会有些粗糙,大家可以选择性阅读. 本篇文章的目的是简单的分析动态代理的原理及模仿JDK Proxy手写一个动态代理以及对几种代理做一个总结. 对于代理模式的介绍和讲解,网 ...

随机推荐

  1. [ 兼容 ] IE和Firefox的Javascript兼容性总结

    长久以来JavaScript兼容性一直是Web开发者的一个主要问题.在正式规范.事实标准以及各种实现之间的存在的差异让许多开发者日夜煎熬.为此,主要从以下几方面差异总结IE和Firefox的Javas ...

  2. 吉布斯现象( Gibbs)

    在连续傅里叶级数(或积分)变换中,信号所对应的离散频谱(或连续频谱)为(或),其频率是无限离散分布的(或频谱的分布范围是无限区间的).很显然,单位时间内,频率较低(简称低频,即较小)的简谐波相对频率较 ...

  3. 学习总结 html一般标签的使用

    body的属性: bgcolor 页面背景色 background  背景壁纸.图片 text  文字颜色 topmargin  上边距 leftmargin   左边距 rightmargin 右边 ...

  4. 什么是动态语言 OC 的runtime

    OC是一门 动态语言. 问题来了.什么是动态语言? 与之相对的静态语言? 学习C++的时候,记得一个名词:“运行时的动态绑定”. 这个是 “多态”的概念. 简单提一下:关键:类指针可以指向本类,或者其 ...

  5. ios assetlibrary

    公司做个app项目,用phonegap做,好调页面,哎,就是骗那些土大款客户,觉得phonegap性能一般吧,不过html5的确好强大,页面设计好了看起来也好看.原生的用的不多,比如什么二维码扫描啊, ...

  6. 【Nginx 3】FTP远程文件下载

    导读:在做项目的过程中,当用户发起申诉时,要上传一个申诉材料.然后后台运营人员在处理申诉时,可能会需要下载申诉材料,进行参考.本篇博客呢,就介绍一下文件的下载! 一.代码实现 <span sty ...

  7. PAT1015. Reversible Primes

    //题的理解是n在基数b中的的表示中,正序和逆序值都是素数,但是其实可直接判断n,因为n在b中的正常序列值就是再换成十进制就是n,但是不A:不知道为什么 用笨方法,先把n展开成b进制,正常计算其实是翻 ...

  8. Mysql group by 排序问题

    类如 有一个 帖子的回复表,posts( id , tid , subject , message , dateline ) , id 为 自动增长字段, tid为该回复的主题帖子的id(外键关联), ...

  9. 使用cnpm搭建企业内部私有NPM仓库

    cnpm是企业内部搭建npm镜像和私有npm仓库的开源方案.它同时解决了现有npm架构的一些问题. 为什么企业需要私有NPM 主要有如下理由: 确保npm服务快速.稳定:对于企业来说,上线生产系统的时 ...

  10. [my]_ubuntu12.10_/etc/apt/sources.list

    deb http://mirrors.163.com/ubuntu/ precise main universe restricted multiverse deb-src http://mirror ...