• 概念

    王宝强有一个经纪人叫宋喆,这个经纪人很吊,可以代理王宝强做一系列的事情,与粉丝活动、王宝强的微博维护、安排王宝强的行程以及什么什么等等。如果王宝强一个人做岂不是累死。通过这个代理人为王宝强节省了不少。

    代理模式就是在不改变原有类的代码结构上为类拓展新的功能。

  • 类图:subject为一个抽象的目标接口,客户端梦想的接口,realSubject为原始类,proxy为代理对象

  

  • 静态代理
//原类与代理类的公共接口
public interface Subject {
public void request();
} public class RealSubject implements Subject{ public void request() {
System.out.println("王宝强拍电影");
}
} public class Proxy implements Subject {
private Subject realSubject; public void setRealSubject(Subject realSubject) {
this.realSubject = realSubject;
} public void request() {
System.out.println("宋喆代替王宝强维护微博");
realSubject.request();
System.out.println("宋喆代替王宝强与粉丝互动");
}
} public class Main {
public static void main(String[] args) {
Subject realSubject=new RealSubject();
Proxy proxy=new Proxy();
proxy.setRealSubject(realSubject);
proxy.request();
}
}
  • 动态代理
public interface Subject {
public void request();
} public class RealSubject implements Subject {
public void request() {
System.out.println("王宝强拍电影");
}
} public class ProxyMain {
public static void main(String[] args) {
final RealSubject realSubject=new RealSubject();
Subject proxy=(Subject) Proxy.newProxyInstance(
/**
* ClassLoader 被代理类的加载器
* Interfaces 代理对象与被代理对象公共接口
* InvocationHandle 事件处理
*/
realSubject.getClass().getClassLoader(),
realSubject.getClass().getInterfaces(),
new InvocationHandler() {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("宋喆代替王宝强维护微博");
Object returnValue=method.invoke(realSubject,args);
System.out.println("宋喆代替王宝强与粉丝互动");
return returnValue;
}
}
);
proxy.request();
}
}
  • Cglib代理
public class RealSubject {
public void request() {
System.out.println("王宝强拍电影");
}
} import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy; import java.lang.reflect.Method; public class ProxyFactory implements MethodInterceptor {
private Object realSubject;
public ProxyFactory(Object realSubject){
this.realSubject=realSubject;
}
public Object getProxyInstance(){
//1.工具类
Enhancer enhancer=new Enhancer();
//2.设置父类
enhancer.setSuperclass(realSubject.getClass());
//3.设置回调函数
enhancer.setCallback(this);
//4.创建子类
return enhancer.create();
}
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy)
throws Throwable {
System.out.println("宋喆代替王宝强维护微博");
Object returnValue=method.invoke(realSubject,objects);
System.out.println("宋喆代替王宝强与粉丝互动");
return returnValue;
}
} public class Main {
public static void main(String[] args) {
RealSubject realSubject=new RealSubject();
RealSubject proxy=
(RealSubject)new ProxyFactory(realSubject)
.getProxyInstance();
proxy.request();
}
}
  • 区别:静态代理与JDK动态代理的区别在于一个是写类去组合目标对象,一个去写匿名内部函数,二者相同之处是原类与代理类必须共同实现目标接口。而Cglib则不用实现目标接口。前两者代码维护性相对于Cglib不方便。
  • 应用场景:AOP切面编程通常可以处理事务管理(开启事务、操作、提交事务)、安全检测(权限验证,进入)、缓存(访问数据库、存入缓存)。AOP默认使用动态代理。
代理对象:拦截真实业务对象的访问
代理对象应该具有和目标对象相同的方法
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
-ClassLoader loader:指明生成代理对象使用哪个类加载器
-Class<?>[] interfaces:指明生成哪个对象的代理对象
-InvocationHandler h:指明这个代理对象要做什么事情 public interface Person{ String sing(String name);
String dance(String name);
} public class LiuDeHua implements Person{
public String sing(String name){
...
}
public String dance(String name){
...
}
} public class LiuDeHuaProxy{ private Person ldh=new LiuDeHua(); public Person getProxy(){
return (Person)Proxy.newProxyInstance(
LiuDeHuaProxy.class.getClassLoader(),
ldh.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy,Method method,Object[]args)throws Throwable{
if(method.getName().equals("sing")){
//调用了sing方法
...
return method.invoke(ldh,args);
}
if(method.getName().equals("dance")){
//调用了dance方法
...
return method.invoke(ldh,args);
}
}
}
)
}
}

最新文章

  1. Atitit smb网络邻居原理与实现查询列表
  2. final关键字用法总结
  3. QT中可以用QProgressBar或着QProgressDialog来实现进度条
  4. HDU 1548 A strange lift 奇怪的电梯(BFS,水)
  5. squid+nginx+apache
  6. python easy_install centos 下安装过程和原理解析
  7. IIS7下w3wp.exe进程CPU100%问题解决办法
  8. 从零开始写一个Tomcat(壹)
  9. Ubuntu 16安装GPU版本tensorflow
  10. springMVC上传
  11. Html 常用标签及属性
  12. Delphi获取本机所有的IP
  13. python基础学习(九)字典
  14. define和typedef的区别
  15. python中的变量和算数运算
  16. 设置将Maven的jar包发布到lib
  17. MATLAB 图形图像处理
  18. iOS:2015年07月最新苹果IOS上架App Store商店步骤
  19. Linux下的fdlisk - l 用法解析-入门篇
  20. Jmeter-返回值乱码处理

热门文章

  1. 【Python】python2.7 安装配置OpenCV2
  2. [转载]IOCP模型的总结
  3. TCP/IP 详解卷一之 HTTP协议
  4. Linux 运维面试问题总结
  5. Arduino 视频教程
  6. windows 代理无法设置上不了网的解决
  7. 使用MeshLab的技巧总结(自己原创总结)
  8. Ext.Net 复制GridPanel的数据
  9. Xilinx SDSoc 加载opencv库
  10. 蓝桥杯T32(树的直径)