• JDK的动态代理


    代理模式中的角色:

    Subject:抽象主题角色,抽象主题类可以是抽象类,也可以是接口,是一个最普通的业务类型定义,无特殊要求。

    RealSubject:具体主题角色,也叫被委托角色、被代理角色。是业务逻辑的具体执行者。

    Proxy:代理主题角色,也叫委托类、代理类。它把所有抽象主题类定义的方法给具体主题角色实现,并且在具体主题角色处理完毕前后做预处理和善后工作。(最简单的比如打印日志):

     

    先创建一个被代理对象,该对象必须继承一个接口(否则jdk无法产生动态代理)

    接口:

    1 package com.bxw.service;
    2 
    3 public interface UserService {
    4     public String getName(int id);
    5     public Integer getAge(int id);
    6 }
    UserService.java

    被代理的对象:

     1 package com.bxw.serviceImpl;
     2 
     3 import com.bxw.service.UserService;
     4 
     5 public class UserServiceImpl implements UserService{
     6 
     7     @Override
     8     public String getName(int id) {
     9         System.out.println("---getNmae---");
    10         return "Tom";
    11     }
    12 
    13     @Override
    14     public Integer getAge(int id) {
    15         System.out.println("---getAge---");
    16         return 17;
    17     }
    18 
    19 }
    UserServiceImpl.java

    Handler:

     1 package com.bxw.invocation;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Method;
     5 
     6 public class MyInvocationHandler implements InvocationHandler {  
     7     //动态代理要有一个被代理的对象
     8     private Object target;  
     9   
    10     MyInvocationHandler() {  
    11         super();  
    12     }  
    13   
    14     public MyInvocationHandler(Object target) {  
    15         super();  
    16         this.target = target;  
    17     }  
    18   
    19     @Override  
    20     public Object invoke(Object o, Method method, Object[] args) throws Throwable {  
    21         if("getName".equals(method.getName())){  
    22             System.out.println("++++++before " + method.getName() + "++++++");  
    23             Object result = method.invoke(target, args);  
    24             System.out.println("++++++after " + method.getName() + "++++++");  
    25             return result;  
    26         }else{  
    27             Object result = method.invoke(target, args);  
    28             return result;  
    29         }  
    30   
    31     }
    32 }
    View Code

    Test:

     1 package com.bxw.test;
     2 
     3 import java.lang.reflect.InvocationHandler;
     4 import java.lang.reflect.Proxy;
     5 
     6 import com.bxw.invocation.MyInvocationHandler;
     7 import com.bxw.service.UserService;
     8 import com.bxw.serviceImpl.UserServiceImpl;
     9 
    10 /**
    11  * jdk要实现动态代理那么该类必须实现一个接口
    12  * @author Admin
    13  *
    14  */
    15 public class TestDemo {
    16      public static void main(String[] args) {  
    17             UserService userService = new UserServiceImpl(); //被代理对象 
    18             InvocationHandler invocationHandler = new MyInvocationHandler(userService);  
    19             //classLoader,interface,产生业务逻辑的Hanfler
    20             UserService userServiceProxy = (UserService)Proxy.newProxyInstance(userService.getClass().getClassLoader(),  
    21                     userService.getClass().getInterfaces(), invocationHandler);//产生的代理对象  
    22             System.out.println(userServiceProxy.getName(1));  
    23             System.out.println(userServiceProxy.getAge(1));  
    24      }  
    25 }
    View Code

     Proxy.newProxyInstance()这个方法有三个参数.第一个是定义代理类型的一个加载者.第二个是要被代理对象的实现的接口列表,第三个是一个对象,这个对象要实现invocationhandler接口的invoke方法来执行你的方法.

    --------------------------分界线-----------------------------

    Cglib代理

     1 package com.bxw.invocation;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 import net.sf.cglib.proxy.Enhancer;
     6 import net.sf.cglib.proxy.MethodInterceptor;
     7 import net.sf.cglib.proxy.MethodProxy;
     8 
     9 public class CglibProxy implements MethodInterceptor {
    10     private Object o;
    11     
    12     public Object getInstance(Object target){
    13         this.o = target;
    14         Enhancer e = new Enhancer();
    15         e.setSuperclass(this.o.getClass());
    16         e.setCallback(this);
    17         return e.create();
    18     }
    19     @Override
    20     public Object intercept(Object o, Method method    , Object[] args,
    21             MethodProxy methodProxy) throws Throwable {
    22         System.out.println("-----before"+methodProxy.getSuperName()+"-----");
    23         System.out.println(method.getName());
    24         //方法、参数
    25         Object o1 = methodProxy.invokeSuper(o, args);
    26         System.out.println("-----after"+methodProxy.getSuperName()+"-----");
    27         return null;
    28     }
    29 
    30 }
    CglibProxy.java

    getInstance用来获得代理类。

    Object o1 = methodProxy.invokeSuper(o, args);注意这里是用invokeSuper方法而不是invoke方法。

     1 package com.bxw.test;
     2 
     3 import com.bxw.invocation.CglibProxy;
     4 import com.bxw.service.UserService;
     5 import com.bxw.serviceImpl.UserServiceImpl;
     6 
     7 public class TestDemo2 {
     8     public static void main(String[] args) {
     9         CglibProxy cl = new CglibProxy();
    10         UserService u = (UserService) cl.getInstance(new UserServiceImpl());
    11         u.getAge(1);
    12         u.getAge(1);
    13     }
    14 }
    Test
  • 相关阅读:
    Hibernate Criteria用法大全
    hibernate数据库操作基础
    Hibernate中Session.get()方法和load()方法的详细比较
    3hibernate核心对象关系映射 xxx.hbm.xml
    2.Hibernate的主配置文件hibernate.cfg.xml
    PHP Switch 语句判断成绩
    PHP页面显示中文字符出现乱码
    windows7下GithubDesktop和极域学生客户端冲突导致无法正常打开解决方案
    关于js特效轮播图练习
    Docker报错总结
  • 原文地址:https://www.cnblogs.com/popcornya/p/6906455.html
Copyright © 2020-2023  润新知