博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JDK代理和CGLIB代理
阅读量:6637 次
发布时间:2019-06-25

本文共 4834 字,大约阅读时间需要 16 分钟。

学而时习之,不亦说乎!

                             --《论语》

AOP是spring的一个重要组成部分,而AOP通过代理实现。这儿写下JDK代理和CGLIB代理两种动态代理,为接下来的Spring AOP做准备。

JDK代理:

1)项目整体结构如下:

 

2)创建maven项目,pom.xml如下:

4.0.0
com.zby
aop
0.0.1-SNAPSHOT
cglib
cglib
3.2.5

这个依赖主要是给CGLIB用的,JDK代理并不需要。

3)创建UserService接口:

package com.zby.service;public interface UserService {	void saveUser(String username, String password);}

4)创建UserService接口实现类UserServiceImpl:

package com.zby.service.impl;import com.zby.service.UserService;public class UserServiceImpl implements UserService {	public void saveUser(String username, String password) {		System.out.println("save user[username=" + username + ",password=" + password + "]");	}}

5)创建CustomAspect切面类:

package com.zby.aspect;public class CustomAspect {	public void startTransaction() {		System.out.println("I get datasource here and start transaction");	}	public void endTrasaction() {		System.out.println("I get datasource here and end transaction");	}}

6)创建JDKProxy代理工厂:

package com.zby.factory;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;import java.lang.reflect.Proxy;import com.zby.aspect.CustomAspect;public class JDKProxy {	public static Object createProxy(final Object targetObj, final CustomAspect customAspect) {		// 使用JDK的Proxy类为目标类创建代理对象		return Proxy.newProxyInstance(				// 目标类使用的类加载器				targetObj.getClass().getClassLoader(),				// 目标类实现的接口				targetObj.getClass().getInterfaces(),				// 执行处理器,代理我们的业务逻辑				new InvocationHandler() {					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {						// 执行切面方法						customAspect.startTransaction();						// 具体逻辑代码执行,返回值为方法执行结果						Object result = method.invoke(targetObj, args);						// 执行切面方法						customAspect.endTrasaction();						// 返回方法执行结果						return result;					}				});	}}

  

7)编写测试代码:

package com.zby.test;import org.junit.Test;import com.zby.aspect.CustomAspect;import com.zby.factory.JDKProxy;import com.zby.service.UserService;import com.zby.service.impl.UserServiceImpl;public class JDKProxyTest {	@Test	public void testJDKProxy() {		System.out.println("before Proxy......");		UserService userService = new UserServiceImpl();		userService.saveUser("zby", "1234567890");		System.out.println("After Proxy......");		UserService proxyUserService = (UserService)JDKProxy.createProxy(userService, new CustomAspect());		proxyUserService.saveUser("zby", "1234567890");	}}

8)控制台打印结果:

before Proxy......save user[username=zby,password=1234567890]After Proxy......I get datasource here and start transactionsave user[username=zby,password=1234567890]I get datasource here and end transaction

CGLIB代理:

1)使用JDK代理创建的UserService接口,UserServiceImpl实现类和CustomAspect切面类。

2)创建CGLIB的代理类CGLIBProxy:

package com.zby.factory;import java.lang.reflect.Method;import com.zby.aspect.CustomAspect;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.MethodProxy;public class CGLIBProxy {	public static Object createProxy(final Object targetObj, final CustomAspect customAspect) {		Enhancer enhancer = new Enhancer();		// 设置需要代理的父类		enhancer.setSuperclass(targetObj.getClass());		// 设置回调		enhancer.setCallback(new MethodInterceptor() {			@Override			public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy)					throws Throwable {				// 执行切面方法				customAspect.startTransaction();				// 具体逻辑代码执行,返回值为方法执行结果				Object result = methodProxy.invokeSuper(proxy, args);				// 执行切面方法				customAspect.endTrasaction();				// 返回方法执行结果				return result;			}		});		// 3.4 创建代理		return enhancer.create();	}}

3)编写测试类:

package com.zby.test;import org.junit.Test;import com.zby.aspect.CustomAspect;import com.zby.factory.CGLIBProxy;import com.zby.service.UserService;import com.zby.service.impl.UserServiceImpl;public class CGLIBProxyTest {	@Test	public void testJDKProxy() {		System.out.println("before Proxy......");		UserService userService = new UserServiceImpl();		userService.saveUser("zby", "1234567890");		System.out.println("After Proxy......");		UserService proxyUserService = (UserService) CGLIBProxy.createProxy(userService, new CustomAspect());		proxyUserService.saveUser("zby", "1234567890");	}}

4)控制台打印结果:

before Proxy......save user[username=zby,password=1234567890]After Proxy......I get datasource here and start transactionsave user[username=zby,password=1234567890]I get datasource here and end transaction

 5)CGLIB代理和JDK代理最大的区别就是:CGLIB代理的对象不需要实现任何接口,它使用的字节码子类代理方式,但是JDK代理的对象必须实现接口。这儿使用CGLIB代理的时候,可以将UserService删除,使用UserServiceImpl接收代理结果,效果完全一样。

6)JDK代理的实质是生成一个实现我们传入的接口,并且继承Proxy的类;Cglib代理实质是继承我们传入的类。

转载于:https://www.cnblogs.com/zby9527/p/6945756.html

你可能感兴趣的文章
Ubuntu 12.04 使用虚拟控制台fberm,显示并可输入中文
查看>>
mac下server开发环境配置
查看>>
IOS研发之路-卸载软件
查看>>
【学习笔记6】Result配置的各种视图转发类型
查看>>
深入讲解RPM包安装/升级/查询/卸载
查看>>
Eclipse使用EGit管理git@OSC项目
查看>>
Ehcache(01)——简介、基本操作
查看>>
idea及其插件sbt,Scala安装配置
查看>>
设计模式--这段很重要
查看>>
java读取指定package下的所有class
查看>>
settimeout 推荐的最小值
查看>>
MySQL 常用命令
查看>>
HttpClient4上传文件
查看>>
centos6.4和Ubuntu14.04搭建SNMP服务
查看>>
为微信小程序增加mixin扩展
查看>>
敏感信息识别方法探究
查看>>
创建一个可执行的python脚本
查看>>
听云APP 图表分析
查看>>
Oracle排名函数运用实例
查看>>
【推荐】[网址]PHP各种开源网站系统、cms系统一览[持续更新]
查看>>