设计模式笔记-代理模式
Posted SingleOneMan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式笔记-代理模式相关的知识,希望对你有一定的参考价值。
设计模式笔记-代理模式
文章目录
1.代理模式
静态代理:静态代理提前编译,代码运行前,直接调用代理类的方法。动态代理是在程序运行时通过反射机制动态创建的。
jdk动态代理:运行期通过反射,调用代理类的方法
cglib代理:CGLib采用了字节码技术,其原理是通过字节码技术为一个代理类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑
2.常见写法
静态代理:
public interface IUserDao
void save();
/**
* 接口实现
* 目标对象
*/
public class UserDao implements IUserDao
public void save()
System.out.println("----已经保存数据!----");
/**
* 代理对象,静态代理
*/
public class UserDaoProxy implements IUserDao
//接收保存目标对象
private IUserDao target;
public UserDaoProxy(IUserDao target)
this.target=target;
public void save()
System.out.println("开始...");
target.save();//执行目标对象的方法
System.out.println("结束...");
public class TestMain
public static void main(String[] args)
//目标对象
UserDao target = new UserDao();
//代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target);
//执行的是代理的方法
proxy.save();
jdk动态代理:
public interface IUserDao
void save();
/**
* 接口实现
* 目标对象
*/
public class UserDao implements IUserDao
public void save()
System.out.println("----已经保存数据!----");
public class ProxyFactory
//维护一个目标对象
private Object target;
public ProxyFactory(Object target)
this.target=target;
/**
* Proxy.newProxyInstance()方法接受三个参数:
*
* ClassLoader loader:指定当前目标对象使用的类加载器,获取加载器的方法是固定的
* Class<?>[] interfaces:指定目标对象实现的接口的类型,使用泛型方式确认类型
* InvocationHandler:指定动态处理器,执行目标对象的方法时,会触发事件处理器的方法
* @return
*/
//给目标对象生成代理对象
public Object getProxyInstance()
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler()
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
//这里就可以进行所谓的AOP编程了
//在调用具体函数方法前,执行功能处理
System.out.println("开始...");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
//在调用具体函数方法后,执行功能处理
System.out.println("结束...");
return returnValue;
);
/**
* jdk动态代理运行期通过反射,调用代理类的方法
*/
public class TestMain
public static void main(String[] args)
// 目标对象
IUserDao target = new UserDao();
// 【原始的类型 】
System.out.println(target.getClass());
// 给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass());
// 执行方法 【代理对象】
proxy.save();
cglib代理:
/**
* 目标对象,没有实现任何接口
*/
public class UserDao
public void save()
System.out.println("----已经保存数据!----");
/**
* Cglib子类代理工厂
* 对UserDao在内存中动态构建一个子类对象
* 2.引入功能包后,就可以在内存中动态构建子类
3.代理的类不能为final,否则报错
4.目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.
*/
public class ProxyFactory implements MethodInterceptor
//维护目标对象
private Object target;
public ProxyFactory(Object target)
this.target = target;
//给目标对象创建一个代理对象
public Object getProxyInstance()
//1.工具类
Enhancer en = new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理对象)
return en.create();
/**
* //obj是代理后的子类 ,method是调用方法 ,args是方法入参 , proxy是MethodProxy代理对象
* @param obj
* @param method
* @param args
* @param proxy
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable
System.out.println("开始...");
//执行目标对象的方法,invoke方法调用的对象没有增强过,invokeSuper方法调用的对象已经是增强了的
Object returnValue = proxy.invokeSuper(target, args);
System.out.println("结束...");
return returnValue;
/**
* CGLib采用了字节码技术,其原理是通过字节码技术为一个代理类创建子类,
* 并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑
*/
public class TestMain
public static void main(String[] args)
//目标对象
UserDao target = new UserDao();
//代理对象// 生成 Cglib 代理类
UserDao proxy = (UserDao)new ProxyFactory(target).getProxyInstance();
//执行代理对象的方法
proxy.save();
3.常见框架中的代理模式
1.AOP用代理模式实现的,有JDK动态代理(需要实现接口)和CGLib代理
2.dubbo中的代理模式
以上是关于设计模式笔记-代理模式的主要内容,如果未能解决你的问题,请参考以下文章