IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 代理模式(基于JDK的动态代理与cglib动态代理) -> 正文阅读

[Java知识库]代理模式(基于JDK的动态代理与cglib动态代理)

代理模式(Proxy)

是通过代理对象访问目标对象,在不修改目标对象方法的基础上增强目标方法,例如日志,事务等功能。代理模式又具体分为两类,静态代理和动态代理。

一、静态代理

代理对象很明确的知道被代理对象是谁,一般在代理类中包含目标类对象属性,为了实现代理对象和被代理对象方法的一致,代理类必须和被代理类实现相同接口。代码示例:

public class DemoDAOImpl implements IDemoDAO{
	@Override
	public void executeInsert() {
		System.out.println("[数据访问操作]:1.连接数据库");
		System.out.println("[数据访问操作]:2.执行InsertSQL");
		System.out.println("[数据访问操作]:3.处理结果");
	}

	@Override
	public void executeUpdate() {
		System.out.println("[数据访问操作]:1.连接数据库");
		System.out.println("[数据访问操作]:2.执行UpdateSQL");
		System.out.println("[数据访问操作]:3.处理结果");
	}
}
/*
 * 静态代理类
 */
public class DemoDAOProxy implements IDemoDAO{

	private IDemoDAO demoDao=new DemoDAOImpl();
	
	@Override
	public void executeInsert() {
		long begin=System.currentTimeMillis();
		System.out.println("[增强]开始执行时间:"+new Date());
		demoDao.executeInsert();
		long end=System.currentTimeMillis();
		System.out.println("[增强]执行结束时间:"+new Date());
		System.out.println("[增强]执行总耗时:"+(end-begin));
	}

	@Override
	public void executeUpdate() {
		
	}

}

二、动态代理

代理对象在编译期不知道被代理对象是谁,只有等到运行期才会动态的得到被代理对象的信息,依赖于反射机制。动态代理主要分为两种,基于JDK的动态代理和cglib动态代理,两者的主要区别在于,前者基于接口实现,后者基于父类继承实现,在SpringAOP中首选第一种,当目标对象没有实现接口时,再选择后者,一般以目标对象为父类继承实现动态代理。
1.基于JDK的动态代理
一般步骤为实现反射包中的InvocationHandler接口,重写invoke方法,用于增强被调用方法,再调用Proxy类的newProxyInstance()方法产生代理对象。
代码示例:

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Date;
/*
 * 代理对象工厂类:用于生产代理对象
 * 基于接口实现
 */
public class JdkProxyFactory  implements InvocationHandler,ProxyFactory{
	private Object targetObject;
	

	public JdkProxyFactory(Object targetObject) {
		super();
		this.targetObject = targetObject;
	}

	//返回代理对象
	public Object createProxy() {
		Class targetClass=targetObject.getClass();
		//Proxy.newProxyInstance产生一个代理对象
		//参数一:代理对象与目标对象要有一致的类加载器
		//参数二:代理对象与目标对象要有一致的实现接口
		//参数三:传入InvocationHandler接口的实现类,用于处理代理对象调用方法时处理的逻辑
		Object proxyObject=Proxy.newProxyInstance(targetClass.getClassLoader(),targetClass.getInterfaces(), this);
		return proxyObject;
	}
	
	
	/**
	 * 参数一:代理对象
	 * 参数二:代理对象被调用的方法
	 * 参数三:被调用放发的参数
	 */
	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		long begin=System.currentTimeMillis();
		System.out.println("[增强]开始执行时间:"+new Date());
		
		Object returnVal=method.invoke(targetObject, args);
		
		long end=System.currentTimeMillis();
		System.out.println("[增强]执行结束时间:"+new Date());
		System.out.println("[增强]执行总耗时:"+(end-begin));
		
		return returnVal;
	}

}

2.基于cglib的动态代理
一般代理工厂需要实现MethodInterceptor(Callback的子接口)接口,并重写intercept方法,用于在代理对象回调时增强目标被代理对象的目标方法,然后调用Enhancer类的create()方法产生代理对象,具体代码如下:

import java.lang.reflect.Method;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/*
 * CgLib动态代理
 * 基于继承实现
 */
public class CglibProxyFactory implements MethodInterceptor,ProxyFactory {
	private Object target;
	
	
	public CglibProxyFactory(Object target) {
		super();
		this.target = target;
	}

	//创建代理对象
	public Object createProxy() {
		Enhancer enhancer=new Enhancer();
		enhancer.setSuperclass(target.getClass());//注入被代理类的父类
		enhancer.setCallback(this);//设置回调
		
		Object proxy=enhancer.create();
		return proxy;
	}


	//参数1:代理对象
	//参数2:目标方法
	//参数3:参数数组
	@Override
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy arg3) throws Throwable {
		
		System.out.println("********************************************");
		Object returnval= method.invoke(target, args);
		System.out.println("********************************************");
		return returnval;
	}

}

以上就是我对代理模式的理解,谢谢阅读,欢迎斧正。

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-21 15:13:47  更:2021-08-21 15:14:25 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 9:52:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码