6.代理模式(设计模式笔记)
2015-08-17 22:23
267 查看
分类:
1:创建型模式:
单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式;
2:结构型模式:
适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式
3:行为型模式:
模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,
解释器模式,状态模式,策略模式,职责链模式,访问者模式。
代理模式:
核心作用:
通过代理,控制对对象的访问!
可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个
方法后做后置代理(即:aop微观实现)
-aop(Aspect Oriented Programming面向切面编程)的核心实现机制!
1.JDK动态代理
此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。
代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。
JDK动态代理只能针对实现了接口的类生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。
如果目标对象没有实现接口,则默认会采用CGLIB代理;
如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。
AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。
核心角色:
1.抽象角色:定义代理角色和真实角色的公共对外方法
2.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
关注真正的业务逻辑
3.代理角色:
实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作
将统一的流程控制放到代理角色中处理
应用场景:
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(rmi)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
-比如你要开发一个大文档查看软件界,大文档中有大的图片,有可能一张图片有100MB,在打开
文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来
进行大图片的打开。
分类:
静态代理(静态定义代理类)
动态代理(动态生成代理类)
jdk自带的动态代理
javaassist字节码操作库实现
cglib
asm(底层使用指令,可维护性较差)
静态代理和动态代理的区别:
静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。抽象角色中(接口)声明的所有方法都被转移到处理器的的一个集中的方法中处理。这样我们可以更加灵活和统一的处理众多的方法
jdk自带的动态代理:
-java.lang.reflect.Proxy 动态生成代理类的对象
-java.lang.reflect.InvocationHandler(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过proxy生成代理类对象时都要指定对应的处理器对象
静态代理demo:
public class Client {
public static void main(String[] args) {
Star realStar = new RealStar();
Star proxy = new ProxyStar(realStar);
proxy.confer();
proxy.signContract();
proxy.bookTicket();
// 只有唱歌时,真实角色才出来唱歌
proxy.sing();
proxy.collectMoney();
/**
* 结果 :
* 代言人交谈
* 代言人签合同
* 代言人卖票
* 周杰伦唱歌
* 代言人收钱
*/
}
}
jdk动态代理demo:
1:创建型模式:
单例模式,工厂模式,抽象工厂模式,建造者模式,原型模式;
2:结构型模式:
适配器模式,桥接模式,装饰模式,组合模式,外观模式,享元模式,代理模式
3:行为型模式:
模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,
解释器模式,状态模式,策略模式,职责链模式,访问者模式。
代理模式:
核心作用:
通过代理,控制对对象的访问!
可以详细控制访问某个(某类)对象的方法,在调用这个方法前做前置处理,调用这个
方法后做后置代理(即:aop微观实现)
-aop(Aspect Oriented Programming面向切面编程)的核心实现机制!
1.JDK动态代理
此时代理对象和目标对象实现了相同的接口,目标对象作为代理对象的一个属性,具体接口实现中,可以在调用目标对象相应方法前后加上其他业务处理逻辑。
代理模式在实际使用时需要指定具体的目标对象,如果为每个类都添加一个代理类的话,会导致类很多,同时如果不知道具体类的话,怎样实现代理模式呢?这就引出动态代理。
JDK动态代理只能针对实现了接口的类生成代理。
2.CGLIB代理
CGLIB(CODE GENERLIZE LIBRARY)代理是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的所有方法,所以该类或方法不能声明称final的。
如果目标对象没有实现接口,则默认会采用CGLIB代理;
如果目标对象实现了接口,可以强制使用CGLIB实现代理(添加CGLIB库,并在spring配置中加入<aop:aspectj-autoproxy proxy-target-class="true"/>)。
AOP包括切面(aspect)、通知(advice)、连接点(joinpoint),实现方式就是通过对目标对象的代理在连接点前后加入通知,完成统一的切面操作。
核心角色:
1.抽象角色:定义代理角色和真实角色的公共对外方法
2.真实角色:实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用
关注真正的业务逻辑
3.代理角色:
实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作
将统一的流程控制放到代理角色中处理
应用场景:
安全代理:屏蔽对真实角色的直接访问。
远程代理:通过代理类处理远程方法调用(rmi)
延迟加载:先加载轻量级的代理对象,真正需要再加载真实对象。
-比如你要开发一个大文档查看软件界,大文档中有大的图片,有可能一张图片有100MB,在打开
文件时不可能将所有的图片都显示出来,这样就可以使用代理模式,当需要查看图片时,用proxy来
进行大图片的打开。
分类:
静态代理(静态定义代理类)
动态代理(动态生成代理类)
jdk自带的动态代理
javaassist字节码操作库实现
cglib
asm(底层使用指令,可维护性较差)
静态代理和动态代理的区别:
静态代理类:由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了。动态代理类:在程序运行时,运用反射机制动态创建而成。抽象角色中(接口)声明的所有方法都被转移到处理器的的一个集中的方法中处理。这样我们可以更加灵活和统一的处理众多的方法
jdk自带的动态代理:
-java.lang.reflect.Proxy 动态生成代理类的对象
-java.lang.reflect.InvocationHandler(处理器接口)
可以通过invoke方法实现对真实角色的代理访问
每次通过proxy生成代理类对象时都要指定对应的处理器对象
静态代理demo:
public interface Star { //面谈 void confer(); //签合同 void signContract(); //订票 void bookTicket(); //唱歌 void sing(); //收钱 void collectMoney(); }
/** * 真实角色 * @author Administrator * */ public class RealStar implements Star { @Override public void confer() { System.out.println("周杰伦谈合同"); } @Override public void signContract() { System.out.println("周杰伦签合同"); } @Override public void bookTicket() { System.out.println("周杰伦卖票"); } @Override public void sing() { System.out.println("周杰伦唱歌"); } @Override public void collectMoney() { System.out.println("周杰伦收钱"); } }
/** * 静态代理类 * @author Administrator * */ public class ProxyStar implements Star { private Star star; public ProxyStar(Star realStar) { this.star = realStar; } @Override public void confer() { System.out.println("代言人交谈"); } @Override public void signContract() { System.out.println("代言人签合同"); } @Override public void bookTicket() { System.out.println("代言人卖票"); } @Override public void sing() { //周杰伦唱歌 star.sing(); } @Override public void collectMoney() { System.out.println("代言人收钱"); } }
public class Client {
public static void main(String[] args) {
Star realStar = new RealStar();
Star proxy = new ProxyStar(realStar);
proxy.confer();
proxy.signContract();
proxy.bookTicket();
// 只有唱歌时,真实角色才出来唱歌
proxy.sing();
proxy.collectMoney();
/**
* 结果 :
* 代言人交谈
* 代言人签合同
* 代言人卖票
* 周杰伦唱歌
* 代言人收钱
*/
}
}
jdk动态代理demo:
public interface Star { //面谈 void confer(); //签合同 void signContract(); //订票 void bookTicket(); //唱歌 void sing(); //收钱 void collectMoney(); }
/** * 真实角色 * @author Administrator * */ public class RealStar implements Star { @Override public void confer() { System.out.println("周杰伦谈合同"); } @Override public void signContract() { System.out.println("周杰伦签合同"); } @Override public void bookTicket() { System.out.println("周杰伦卖票"); } @Override public void sing() { System.out.println("周杰伦唱歌"); } @Override public void collectMoney() { System.out.println("周杰伦收钱"); } }
/** * 统一的处理器类 */ public class StartHandler implements InvocationHandler { //这里声明真实角色 Star realStar; public StartHandler(Star realStar) { this.realStar = realStar; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object obj = null; //调用前的操作 System.out.println("谈合同"); if(method.getName().equals("sing")) { obj = method.invoke(realStar, args); } //调用后的操作 System.out.println("收钱"); return obj; } }
public class Clenet { public static void main(String[] args) { Star realStar = new RealStar(); StartHandler handler = new StartHandler(realStar); Star proxy = (Star) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Star.class},handler); proxy.sing(); /** * 结果: * 谈合同 周杰伦唱歌 收钱 */ } }
相关文章推荐
- iOS 实现脉冲雷达以及动态增减元素 By Swift
- socket 网络编程快速入门(一)教你编写基于UDP/TCP的服务(客户端)通信
- poj1026 Cipher
- Knowledge Generation Model for Visual Analytics 第二部分
- androidL init 进程源码分析
- UIButton,UIView,UITextField
- python中的数据结构 之 list列表
- 最短路 Dijkstra算法(CDOJ 最短路)
- 一些常见的warning
- android入门(二) 第一个android程序:FuckWorld
- 重构1-5
- Linux发展史精简总结
- Android 插件化 动态升级
- HDU 5831(思路题目)
- Android软件安全与逆向分析笔记(3)
- 高并发事务处理方案 秒杀的分析
- 修改Hosts不生效的一个场景-web(转)
- C++学习:任意合法状态下汉诺塔的移动(原创)
- C# string.Format字符串格式化
- MySQL-python的安装