码迷,mamicode.com
首页 > 其他好文 > 详细

代理模式

时间:2019-06-30 09:36:21      阅读:82      评论:0      收藏:0      [点我收藏+]

标签:str   执行   静态   运行时   text   cer   ide   factor   val   

Java有三种代理模式:静态代理、jdk动态代理、cglib代理
    • 静态代理
      目的是对目标类的功能进行扩展
      //接口
      public interface ISing){
         public void msg();
      }
      //目标类
      public class Sing implements ISing{
          public void msg(){
          System.out.println("我在唱歌...");
         }
      }
      //代理类
      public class SingProxy  implements ISing{
          private Sing sing;
          public SingProxy( Sing s){
          this.sing=s;
      }
      public void msg(){
          //此处为额外添加的功能...
          this.sing.msg();
          //此处为额外添加的功能...
             }
      }
      //主类
      public class Main{
          public static void main(String[] args){
          //目标对象
          ISing sing=new Sing();
          //代理对象
          SingProxy singProxy=new SingProxy(sing);
          //本质是执行目标对象的方法
          singProxy.msg();
         }
      }
      • jdk动态代理
      静态代理的缺点是要提前写出代理类,jdk动态代理则可以在运行时动态生成代理类,java底层封装了实现细节,所以代码非常简单,格式写法固定:调用Proxy类的静态方法newProxyInstance(),该方法会返回一个代理类的对象,该方法为
      static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,InvocationHandler h )
      接收的三个参数依次为
      • ClassLoader loader:指定目标对象使用的类加载器,写法固定
      • Class<?>[] interfaces:指定目标对象实现的接口,写法固定
      • InvocationHandler h:事件处理接口,需传入一个实现类,一般直接使用匿名内部类
      //代码写法固定
      public class Test{
            public static void main(String[] args) {
                Sing target = new Sing();
                ISing singProxy  = (ISinger) Proxy.newProxyInstance(
                        target.getClass().getClassLoader(),
                        target.getClass().getInterfaces(),
                        new InvocationHandler() {
                            @Override
                            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                               System.out.println("此处为额外实现的功能...");
                               //执行目标对象方法
                               Object returnValue = method.invoke(target, args);
                               System.out.println("此处为额外实现的功能...");
                               return returnValue;
                           }
                       });
              //调用后的本质是执行目标的msg方法
               singProxy.msg();
           }    
       静态代理和JDK代理类都必须实现一个或多个接口,若没有,则可以使用cglib代理。
      • cglib代理
        cglib代理也叫作子类代理,它构建一个目标类的子类(作为代理类),进而添加额外的功能,在Spring的AOP中,如果加入容器的目标类有实现接口,用JDK代理,若没有实现接口,用cglib代理。cglib代理对目标类的要求:
      Spring的核心包中已经包括了cglib功能,需直接引入spring-core-3.2.5.jar;
      目标类不能为final修饰;
      目标类的对象方法如果为final/static,那么就不会被拦截,即不会执行额外的功能,此时cglib失效;
      //目标类(没有接口)
      public class Sing{
          public void msg(){
          System.out.println("我在唱歌...");
         }
      }
      
      //Cglib工厂类
        public class ProxyFactory implements MethodInterceptor{
            // 维护目标对象
            private Object target;
            public ProxyFactory(Object target) {
                this.target = target;
           }
           // 给目标对象创建一个子类对象(子类代理对象,子类做代理类)
           public Object getProxyInstance(){
               //1.工具类
               Enhancer en = new Enhancer();
               //2.设置父类
               en.setSuperclass(target.getClass());
               //3.设置回调函数
               en.setCallback(this);
               //4.创建目标类的子类对象(子类代理对象)
               return en.create();
          }
      //代码写法固定
           @Override
           public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
               System.out.println("此处为额外实现的功能...");
               //执行目标对象的方法
               Object returnValue = method.invoke(target, args);
               System.out.println("此处为额外实现的功能...");
               return returnValue;
           }
       }
      
      //主类
      public class Main{
                 public static void main(String[] args){
                //目标对象,没有接口
                Sing target = new Sing();
                //代理对象
                Sing proxy = (Sing)new ProxyFactory(target).getProxyInstance();
                proxy.msg();//执行子类代理对象的方法
           }
       }
       
       

代理模式

标签:str   执行   静态   运行时   text   cer   ide   factor   val   

原文地址:https://www.cnblogs.com/afei1759/p/11108466.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!