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);
     }
  1. 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);// 判断是否属于被代理对象类型
     }