JAVA两种代理模式
简单设计动态代理,基本模拟spring的动态代理方式。
before afterReturning around afterException after这些通知方法都可以这块模拟出来
spring的AOP:
1.在容器中的对象如果实现了接口则采用JDK的动态代理。
2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。
现在模拟spring的动态代理。
首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。
public interface UserService { void save(); }
public class UserServiceImpl implements UserService { public void save() {
System.out.println("保存用户");
} }
1.动态代理
/**
* 动态代理1
*
* @author shihaibin
* @param <T>
*
*/
public class UserServiceProxyFactory implements InvocationHandler { Object impl; public <T> Object getProxy(Class<T> clz) {
try {
impl = clz.newInstance();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 生成动态代理
Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);
// 返回
return usProxy;
} /**
* 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
before();
Object invoke = method.invoke(impl, args);
after();
return invoke;
}
//可以重写
public void before() {
System.out.println("之后");
} public void after() {
System.out.println("之后");
}
}
测试:
@Test
public void find1() {
// 简单的aop
UserServiceProxyFactory factory = new UserServiceProxyFactory();
UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);
userServiceProxy.save();
System.out.println(userServiceProxy instanceof UserServiceImpl);
}
2.cglib代理
/**
* 动态代理2 cglib代理
*
* @author shihaibin
*
*/
public class UserServiceProxyFactory2 implements MethodInterceptor { public <T> Object getProxy(Class<T> clz) {
Enhancer en = new Enhancer();// 帮我们生成代理对象
en.setSuperclass(clz);// 设置对谁进行代理
en.setCallback(this);//回调函数
return en.create();// 创建代理对象;
} /**
* prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法
*/
public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
// 打开事务
System.out.println("打开事务!");
// 调用原有方法
Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);
// 提交事务
System.out.println("提交事务!");
return invokeSuper;
}
}
测试:
@Test
public void find2() {
// 重写aop前后方法
UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2();
UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class);
userServiceProxy.save();
// 判断代理对象是否属于被代理对象类型
// 代理对象继承了被代理对象=>true
System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型
}
JAVA两种代理模式的更多相关文章
- JAVA学习篇--JAVA两种编程模式控制
在Drp项目中,解说了两种编程模式Model 1和Model2.以下是对这两种模式的简单理解.以及因为Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对照学习一下. ...
- Java三种代理模式
本文转自:https://mp.weixin.qq.com/s/nBmbNP2mR7ei-lDsuOxjWg 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象 ...
- Java三种代理模式:静态代理、动态代理和cglib代理
一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...
- 两种代理模式(JDK和Cglib)实例
CGlib代理模式: package CGLIB; import java.lang.reflect.Method; import JDK.Test; import net.sf.cglib.prox ...
- Java的三种代理模式&完整源码分析
Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCache缓存的实现机制](https://www.c ...
- JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解
在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...
- java web学习总结(二十九) -------------------JavaBean的两种开发模式
SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...
- Java的三种代理模式
Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...
- Java的三种代理模式简述
本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...
随机推荐
- hbase copyTable
参考:https://yq.aliyun.com/articles/176546 执行:hbase org.apache.hadoop.hbase.mapreduce.CopyTable --new. ...
- mysql保留两位小数
--这个是保留整数位 SELECT CONVERT(4545.1366,DECIMAL); --这个是保留两位小数 ,)); --这个是截取两位,并不会四舍五入保留两位小数 );
- c#调用本地命令并截取Output
demo1: /// <summary> /// /// </summary> /// <param name="str"></param ...
- 另一个SqlParameterCollection中已包含SqlParameter(转)
一般情况下,我们定义的一个SqlParameter参数数组,如: SqlParameter[] parms = { new SqlParamete ...
- nginx为什么性能这么优越?
Nginx (“engine x”) 是一个高性能的 HTTP 和 反向代理 服务器 ,也是一个 IMAP/POP3/SMTP 代理 服务器 . Nginx 是由 Igor Sysoev 为俄罗斯访问 ...
- SimpleScalar Course Project
https://blog.csdn.net/wahaha_nescafe/article/details/8500186 https://blog.csdn.net/wahaha_nescafe/ar ...
- 开包即食的教程带你浅尝最新开源的C# Web引擎Blazor
在今年年初,恰逢新春佳节临近的时候.微软给全球的C#开发者们,着实的送上了一分惊喜.微软正式开源Blazor,将.NET带回到浏览器. 这个小惊喜,迅速的在dotnet开发者中间传开了.201 ...
- Bash:常用命令工具-tr命令
tr命令可以用来做简单的字符替换与删除,常用的有-d, -s选项.它的替换与删除是按单个字符来的 假设有以下文本: Read from the file words.txt and output th ...
- js-权威指南学习笔记15
第十五章 脚本化文档 1.文档对象模型DOM是表示和操作HTML和XML文档内容的基础API. 2.Document.Element.Text是Node的子类. 3.查询文档的一个或多个元素有如下方法 ...
- 根据多个点使用canvas贝赛尔曲线画一条平滑的曲线
众所周知想用canvas画一条曲线我们可以使用这些函数: 二次曲线:quadraticCurveTo(cp1x, cp1y, x, y) 贝塞尔曲线:bezierCurveTo(cp1x, cp1y, ...