简单设计动态代理,基本模拟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两种代理模式的更多相关文章

  1. JAVA学习篇--JAVA两种编程模式控制

    在Drp项目中,解说了两种编程模式Model 1和Model2.以下是对这两种模式的简单理解.以及因为Model2是基于MVC架构的模式,就将我们易混淆的MVC与我们之前学的三层架构进行对照学习一下. ...

  2. Java三种代理模式

    本文转自:https://mp.weixin.qq.com/s/nBmbNP2mR7ei-lDsuOxjWg 代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象 ...

  3. Java三种代理模式:静态代理、动态代理和cglib代理

    一.代理模式介绍 代理模式是一种设计模式,提供了对目标对象额外的访问方式,即通过代理对象访问目标对象,这样可以在不修改原目标对象的前提下,提供额外的功能操作,扩展目标对象的功能. 简言之,代理模式就是 ...

  4. 两种代理模式(JDK和Cglib)实例

    CGlib代理模式: package CGLIB; import java.lang.reflect.Method; import JDK.Test; import net.sf.cglib.prox ...

  5. Java的三种代理模式&完整源码分析

    Java的三种代理模式&完整源码分析 参考资料: 博客园-Java的三种代理模式 简书-JDK动态代理-超详细源码分析 [博客园-WeakCache缓存的实现机制](https://www.c ...

  6. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  7. java web学习总结(二十九) -------------------JavaBean的两种开发模式

    SUN公司推出JSP技术后,同时也推荐了两种web应用程序的开发模式,一种是JSP+JavaBean模式,一种是Servlet+JSP+JavaBean模式. 一.JSP+JavaBean开发模式 1 ...

  8. Java的三种代理模式

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  9. Java的三种代理模式简述

    本文着重讲述三种代理模式在java代码中如何写出,为保证文章的针对性,暂且不讨论底层实现原理,具体的原理将在下一篇博文中讲述. 代理模式是什么 代理模式是一种设计模式,简单说即是在不改变源码的情况下, ...

随机推荐

  1. Android 开发工具类 03_HttpUtils

    Http 请求的工具类: 1.异步的 Get 请求: 2.异步的 Post 请求: 3.Get 请求,获得返回数据: 4.向指定 URL 发送 POST方法的请求. import java.io.Bu ...

  2. InterView之PHP2

    PHP 理论知识 常用的超全局变量(8个) $_GET ----->get传送方式 $_POST ----->post传送方式 $_REQUEST ----->可以接收到get和po ...

  3. Nodejs学习笔记(十)—与MongoDB的交互(mongodb/node-mongodb-native)、MongoDB入门

    简介 MongoDB 开源,高性能的NoSQL数据库:支持索引.集群.复制和故障转移.各种语言的驱动程序:高伸缩性: NoSQL毕竟还处于发展阶段,也有说它的各种问题的:http://coolshel ...

  4. 精度更高的double类型计算工具类(借助BigDecimal类型)

    /** * 提供精確的加法運算 * @param args */ public static double add(double v1, double v2) { BigDecimal b1 = ne ...

  5. 理解Spring定时任务的fixedRate和fixedDelay

    用过  Spring 的 @EnableScheduling 的都知道,我们用三种形式来部署计划任务,即 @Scheduled 注解的 fixedRate(fixedRateString), fixe ...

  6. HAProxy Installation and Configuration on CentOS 6.4 to Mitigate The Effects of Abusive Clients--转

    ref:http://thoughts.z-dev.org/2013/05/07/haproxy-installation-and-configuration-on-centos-6-4-to-mit ...

  7. ruby 数组操作

    数组的创建 arr = Array.new num #创建num个元素的数组,所有数组元素为nil arr = Array.new num, elem #创建num个元素的数组,所有数组元素为elem ...

  8. nodejs zip压缩版安装与配置

    Node.js 1.下载 下载地址:https://nodejs.org/zh-cn/download/ 选择相应的版本下载 2.解压缩 将文件解压到要安装的位置,并新建两个目录 node-globa ...

  9. 不会几个框架,都不好意思说搞过前端: Node.js & angular.js

    Node.js  菜鸟教程 :http://www.runoob.com/nodejs/nodejs-install-setup.html angular.js  菜鸟教程 :http://www.r ...

  10. javascript中字符串常用操作总结

    String对象属性 (1) length属性 length算是字符串中非常常用的一个属性了,它的功能是获取字符串的长度.当然需要注意的是js中的中文每个汉字也只代表一个字符,这里可能跟其他语言有些不 ...