静态代理和动态代理简介

举报
yd_273762914 发表于 2020/12/03 00:05:41 2020/12/03
【摘要】 文章目录 第一章 前言第二章 静态代理第三章 动态代理3.1 JDK动态代理3.2 CGLIB动态代理 第一章 前言 在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服...

第一章 前言

在某些情况下,一个客户不想或者不能直接引用一个对象,此时可以通过一个称之为“代理”的第三者来实现间接引用。代理对象可以在客户端和目标对象之间起到中介的作用,并且可以通过代理对象去掉客户不能看到的内容和服务或者添加客户需要的额外服务。
代理模式的角色分为:
主题接口: 即代理类的所实现的行为接口。
目标对象: 也就是被代理的对象。
代理对象: 用来封装真是主题类的代理类
客户端:即用来实现的类
这里写图片描述

代理模式分为静态代理和动态代理 • 静态代理:静态代理就是编译阶段就生成代理类来完成对代理对象的一系列操作。
• 动态代理:动态代理是指在运行时动态生成代理类。即,代理类的字节码将在运行时生成并载入当前代理的 ClassLoader。

第二章 静态代理

静态代理:静态代理就是编译阶段就生成代理类来完成对代理对象的一系列操作。
主题接口:

public   interface Subject  { abstract   public   void  request(); 
} 
  
 
  • 1
  • 2
  • 3

目标对象:

public   class  RealSubject  implements Subject  { public   void  request()  { System.out.println( " From real subject. " ); }  
}  

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

代理对象:

public   class  StaticProxySubject  implements Subject  { private  RealSubject  realSubject;  // 以真实角色作为代理角色的属性 public  ProxySubject()  { } public  void  request()  {  // 该方法封装了真实对象的request方法 //懒加载,用的时候才加载
	if ( realSubject  ==   null  )  { realSubject  =   new  RealSubject(); } realSubject.request();  // 此处执行真实对象的request方法 } 
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

编写客户端类:

public class Client{
	StaticProxySubject sps = new StaticProxySubject();
	sps.request();
}

  
 
  • 1
  • 2
  • 3
  • 4

第三章 动态代理

动态代理:动态代理是指在运行时动态生成代理类。即,代理类的字节码将在运行时生成并载入当前代理的 ClassLoader。
生成动态代理的方法有很多: JDK中自带动态代理,CGlib, javassist等。

3.1 JDK动态代理

Proxy类。该类即为动态代理类,该类最常用的方法为:public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException

newProxyInstance()方法用于根据传入的接口类型interfaces返回一个动态创建的代理类的实例,方法中第一个参数loader表示代理类的类加载器,第二个参数interfaces表示被代理类实现的接口列表,第三个参数h表示所指派的调用处理程序类。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class MyInvocationHandler implements InvocationHandler { private Class<?> target;//委托类 public MyInvocationHandler(Class<?> target){ this.target=target; }
	//实际执行类bind public  Object bind(Class<?> target){ //利用JDK提供的Proxy实现动态代理 return  Proxy.newProxyInstance(target.getClassLoader(), new Class[]{target},this); } @Override public Object invoke(Object o, Method method, Object[] args) throws Throwable {
		/**代理环绕**/ //执行实际的方法 Object invoke = method.invoke(target, args); return invoke; }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3.2 CGLIB动态代理

CGLIB动态代理实现相关类需要在项目中导入 cglib-nodep-2.1_3.jar ,主要涉及两个类:
MethodInterceptor接口。它是代理实例的调用处理程序实现的接口,该接口中定义了如下方法:public Object intercept(Object proxy, Method method, Object[] arg2, MethodProxy mp);

intercept()方法中第一个参数proxy表示代理类,第二个参数method表示需要代理的方法,第三个参数args表示代理方法的参数数组,第四个参数mp用 来去调用被代理对象方法

package com.demo;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class MyInterceptor implements MethodInterceptor{ private Object target; ;//代理的目标对象 public MyInterceptor(Object target) { this.target = target; } 
//proxy 在其上调用方法的代理实例 method拦截的方法 args  拦截的参数
 //invocation 用来去调用被代理对象方法 @Override public Object intercept(Object proxy, Method method, Object[] args, MethodProxy invocation) throws Throwable { //1.记录日志 2.时间统计开始   3.安全检查 Object retVal = invocation.invoke(target, args); //4.时间统计结束 return retVal; }
//创建代理对象的方法 public Object proxy(Object target) {
		this.target = target;
		Enhancer enhancer = new Enhancer();//该类用于生成代理类 enhancer.setSuperclass(this.target.getClass());//设置父类
		enhancer.setCallback(this);//设置回调用对象为本身
		return enhancer.create(); }
}


  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

文章来源: smilenicky.blog.csdn.net,作者:smileNicky,版权归原作者所有,如需转载,请联系作者。

原文链接:smilenicky.blog.csdn.net/article/details/75115928

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。