一、代理概念 
为某个对象提供一个代理,以控制对这个对象的访问。 代理类和委托类有共同的父类或父接口,这样在任何使用委托类对象的地方都可以用代理对象替代。代理类负责请求的预处理、过滤、将请求分派给委托类处理、以及委托类执行完请求后的后续处理。

二.代理模式

从图中可以看出,代理接口(Subject)、代理类(ProxySubject)、委托类(RealSubject)形成一个“品”字结构。 
根据代理类的生成时间不同可以将代理分为静态代理和动态代理两种。

下面以一个模拟需求说明静态代理和动态代理:委托类要处理一项耗时较长的任务,客户类需要打印出执行任务消耗的时间。解决这个问题需要记录任务执行前时间和任务执行后时间,两个时间差就是任务执行消耗的时间。

二、静态代理 
由程序员创建或工具生成代理类的源码,再编译代理类。所谓静态也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。

接下来,我们来看看静态代理的案例

先定义一个接口类

package aop005;

public interface Girl {
public void KFC(String datetime);
public void meet(String datetime);
}

然后分别定义两个类

package aop005;

/*
*
*/
public class Girl1 implements Girl{ public void KFC(String datetime){ System.out.println("[核心业务逻辑]我是第一个女孩");
System.out.println("[核心业务逻辑]"+datetime+"吃肯德基");
} public void meet(String datetime){ System.out.println("[核心业务逻辑]我是第一个女孩");
System.out.println("[核心业务逻辑]"+datetime+"约会"); } }
package aop005;

/*
*
*/
public class Girl2 implements Girl { public void KFC(String datetime){
System.out.println("[核心业务逻辑]我是第二个女孩");
System.out.println("[核心业务逻辑]"+datetime+"吃肯德基");
} public void meet(String datetime){
System.out.println("[核心业务逻辑]我是第二个女孩");
System.out.println("[核心业务逻辑]"+datetime+"约会");
} }

接着我们建一个静态代理类

package aop005;

/*
* 本例是静态代理
* 1、经纪人和要明星,必须实现同一个接口
* 2、把明星作为一个本类的一个属性,用于调用
*/
public class GirlProxy implements Girl {
private Girl g; public GirlProxy(String name){
if ("girl1".equals(name)){
g = new Girl1();
}else if ("girl2".equals(name)){
g = new Girl2();
}
} @Override
public void KFC(String datetime) {
System.out.println("洗澡");
System.out.println("化妆");
System.out.println("穿衣服");
System.out.println("*****************"); g.KFC(datetime); System.out.println("*****************");
System.out.println("卸妆");
System.out.println("洗澡");
System.out.println("睡觉");
} @Override
public void meet(String datetime) {
System.out.println("洗澡");
System.out.println("化妆");
System.out.println("穿衣服");
System.out.println("*****************"); g.meet(datetime); System.out.println("*****************");
System.out.println("卸妆");
System.out.println("洗澡");
System.out.println("睡觉");
} }

接着我们来弄一个测试类

package aop005;

/*
* 增加一个【静态代理类】,类似与明星的经纪人
* 把核心的业务逻辑的代码 和 非核心的 分离
* 把非核心的代码交给经纪人(proxy)去管理,
* 注意:经纪人和要明星,必须实现同一个接口
*
* 缺点:
* 1.每个点都需要写一次
* 2.当分离出来的非核心代码,如果一旦需要修改,那么全体都要改
*/
public class Test { public static void main(String[] args) { Girl g1 = new GirlProxy("girl1");
Girl g2 = new GirlProxy("girl2"); g1.KFC("周六");
g1.meet("周日"); g2.KFC("周六");
g2.meet("周日");
} }

测试结果如下:

通过上面的案例我们可以发现,如果我们如果我们需要改非核心的业务代码,那我们这里就要改2次。

换句话说:我们有几个非核心业务我们就要改几次。

这也就为我们后面为什么要使用动态代理做了铺垫。

spring静态代理的更多相关文章

  1. Spring 静态代理+JDK动态代理和CGLIB动态代理

    代理分为两种:静态代理 动态代理 静态代理:本质上会在硬盘上创建一个真正的物理类 动态代理:本质上是在内存中构建出一个类. 如果多个类需要进行方法增强,静态代理则需要创建多个物理类,占用磁盘空间.而动 ...

  2. spring静态代理和动态代理

    本节要点: Java静态代理 Jdk动态代理 1 面向对象设计思想遇到的问题 在传统OOP编程里以对象为核心,并通过对象之间的协作来形成一个完整的软件功能,由于对象可以继承,因此我们可以把具有相同功能 ...

  3. Spring 静态代理和动态代理

    现在我们来模拟一下,某位学生去考试. 假设他(小明)正常的考试. 运行结果:        结果: 突然某一天,他睡过头了,来不急去考试,所有他打算叫另一个人(Cheater)去代替他考试. 运行结果 ...

  4. Spring学习总结(二)——静态代理、JDK与CGLIB动态代理、AOP+IoC

    一.为什么需要代理模式 假设需实现一个计算的类Math.完成加.减.乘.除功能,如下所示: package com.zhangguo.Spring041.aop01; public class Mat ...

  5. 【spring 3】AOP:静态代理

    一.代理的基本简介 首先,在什么时候使用代理: 在面向方面编程过程中,当需要对所有类进行某种操作(如,安全性检查,记录操作日志)时,考虑到OCP原则,我们不能在所有实现类中直接添加某些相关方法,这样一 ...

  6. Spring框架_代理模式(静态代理,动态代理,cglib代理)

    共性问题: 1. 服务器启动报错,什么原因? * jar包缺少.jar包冲突 1) 先检查项目中是否缺少jar包引用 2) 服务器: 检查jar包有没有发布到服务器下:                 ...

  7. spring AOP 动态代理和静态代理以及事务

    AOP(Aspect Oriented Programming),即面向切面编程 AOP技术,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装 ...

  8. java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. ...

  9. Mybaits 源码解析 (十一)----- 设计模式精妙使用:静态代理和动态代理结合使用:@MapperScan将Mapper接口生成代理注入到Spring

    上一篇文章我们讲了SqlSessionFactoryBean,通过这个FactoryBean创建SqlSessionFactory并注册进Spring容器,这篇文章我们就讲剩下的部分,通过Mapper ...

随机推荐

  1. Solr4.0 如何配置使用UUID自动生成id值

    原文链接http://blog.csdn.net/keepthinking_/article/details/8501058#comments 最近学习了Lucene,随便也学习了Solr,Solr规 ...

  2. mysql5.7安装

    用到的命令和文件: 错误日志:/usr/local/mysql/data/carydeMBP.lan.err 忘记密码时,关闭mysql的密码登陆验证:mysqld_safe --skip-grant ...

  3. MVC 定时执行任务

    环境:.net4.5 需求:需要一个方法定时执行任务 解决: System.Threading.Timer 提供以指定的时间间隔执行方法的机制. 此类不能被继承,有10多种实例化方法,满足多种情况. ...

  4. Reverse Core 第二部分 - 16&17章 - 基址重定位表&.reloc节区

    第16-17章 - 基址重定位表&.reloc节区 @date: 2016/11/31 @author: dlive 0x00 前言 这几天忙着挖邮箱漏洞,吃火锅,马上要被关禁闭,看书进度比较 ...

  5. 基于netty轻量的高性能分布式RPC服务框架forest<上篇>

    工作几年,用过不不少RPC框架,也算是读过一些RPC源码.之前也撸过几次RPC框架,但是不断的被自己否定,最近终于又撸了一个,希望能够不断迭代出自己喜欢的样子. 顺便也记录一下撸RPC的过程,一来作为 ...

  6. java实现记住密码功能(利用cookie)

    <br> <input type="text" id="userName" name="userName" value=& ...

  7. 修改git的远程仓库命令

    1. 修改命令 git remte origin set-url URL 2.先删后加 git remote rm origin git remote add origin git@github.co ...

  8. PHP预定义接口之 ArrayAccess

    最近这段时间回家过年了,博客也没有更新,感觉少学习了好多东西,也错失了好多的学习机会,就像大家在春节抢红包时常说的一句话:一不留神错过了好几亿.废话少说,这篇博客给大家说说关于PHP预定义接口中常用到 ...

  9. CRC循环冗余校验码总结(转)

    转自 http://blog.csdn.net/u012993936/article/details/45337069 一.CRC简介 先在此说明下什么是CRC:循环冗余码校验 英文名称为Cyclic ...

  10. Jenkins 2.16.3默认没有Launch agent via Java Web Start,如何配置使用

    问题:Jenkins 2.16.3默认没有Launch agent via Java Web Start,如下图所示,而这种启动方式在Windows上是最方便的. 如何设置才能让出来呢? 打开&quo ...