zoukankan      html  css  js  c++  java
  • JAVA两种代理模式

    简单设计动态代理,基本模拟spring的动态代理方式。

    before afterReturning around afterException after这些通知方法都可以这块模拟出来

    spring的AOP: 

    1.在容器中的对象如果实现了接口则采用JDK的动态代理。

    2在容器中的对象没有实现接口,则用(cglib)继承的方式实现动态代理。

    现在模拟spring的动态代理。

    首先准备接口(UserService)和实现接口的目标对象(UserServiceImpl)。

    1 public interface UserService {
    2 
    3 void save(); 
    4 
    5 }
    1 public class UserServiceImpl implements UserService {
    2 
    3     public void save() {
    4         System.out.println("保存用户");
    5     } 
    6 
    7 }

    1.动态代理

     1 /**
     2  * 动态代理1
     3  * 
     4  * @author shihaibin
     5  * @param <T>
     6  *
     7  */
     8 public class UserServiceProxyFactory implements InvocationHandler {
     9 
    10     Object impl;
    11 
    12     public <T> Object getProxy(Class<T> clz) {
    13         try {
    14             impl = clz.newInstance();
    15         } catch (InstantiationException e) {
    16             // TODO Auto-generated catch block
    17             e.printStackTrace();
    18         } catch (IllegalAccessException e) {
    19             // TODO Auto-generated catch block
    20             e.printStackTrace();
    21         }
    22         // 生成动态代理
    23         Object usProxy = Proxy.newProxyInstance(clz.getClassLoader(), clz.getInterfaces(), this);
    24         // 返回
    25         return usProxy;
    26     }
    27 
    28     /**
    29      * 参数:1.当前代理對象 2.当前方法 3.当前方法执行的时候的参数
    30      */
    31     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    32         before();
    33         Object invoke = method.invoke(impl, args);
    34         after();
    35         return invoke;
    36     }
    37     //可以重写
    38     public void before() {
    39         System.out.println("之后");
    40     }
    41 
    42     public void after() {
    43         System.out.println("之后");
    44     }
    45 }

    测试:

    1 @Test
    2     public void find1() {
    3         // 简单的aop
    4         UserServiceProxyFactory factory = new UserServiceProxyFactory();
    5         UserService userServiceProxy = (UserService) factory.getProxy(UserServiceImpl.class);
    6         userServiceProxy.save(); 
    7         System.out.println(userServiceProxy instanceof UserServiceImpl);
    8     }

    2.cglib代理

     1 /**
     2  * 动态代理2 cglib代理
     3  * 
     4  * @author shihaibin
     5  *
     6  */
     7 public class UserServiceProxyFactory2 implements MethodInterceptor {
     8 
     9     public <T> Object getProxy(Class<T> clz) {
    10         Enhancer en = new Enhancer();// 帮我们生成代理对象
    11         en.setSuperclass(clz);// 设置对谁进行代理
    12         en.setCallback(this);//回调函数
    13         return en.create();// 创建代理对象;
    14     }
    15 
    16     /**
    17      * prxoyobj:被代理的原始对象 method:被代理的原始方法 arg:运行期的参数 methodProxy:产生的代理方法
    18      */
    19     public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
    20         // 打开事务
    21         System.out.println("打开事务!");
    22         // 调用原有方法
    23         Object invokeSuper = methodProxy.invokeSuper(prxoyobj, arg);
    24         // 提交事务
    25         System.out.println("提交事务!");
    26         return invokeSuper;
    27     }
    28 }

    测试:

     1 @Test
     2     public void find2() {
     3         // 重写aop前后方法
     4         UserServiceProxyFactory2 factoryContext = new UserServiceProxyFactory2();
     5         UserService userServiceProxy = (UserService) factoryContext.getProxy(UserServiceImpl.class);
     6         userServiceProxy.save();
     7         // 判断代理对象是否属于被代理对象类型
     8         // 代理对象继承了被代理对象=>true
     9         System.out.println(userServiceProxy instanceof UserServiceImpl);// 判断是否属于被代理对象类型
    10     }
  • 相关阅读:
    12.19手动 项目部署
    12.19 redis缓存
    12.19 redis缓存
    用压测模拟并发、并发处理(synchronized,redis分布式锁)
    12.19 异常捕获补充
    app提交版本更新的流程
    变量
    类型转换的判别
    本文档中使用的伪类型
    Callbacks
  • 原文地址:https://www.cnblogs.com/shihaibin821/p/9244357.html
Copyright © 2011-2022 走看看