zoukankan      html  css  js  c++  java
  • Java代理模式

     一、代理模式的介绍

           代理模式,是指对一个对象提供一种代理以控制对这个对象的访问。使用代理对象,是为了在不修改目标对象的基础上,增强主业务逻辑。

           客户类真正想访问的是目标对象,但客户类可以访问的对象是代理对象。可以以“代理律师”来理解“代理模式”。

    二、包的命名

          JAVA中包的命名一般分为4-5层:

         1、甲方公司域名的倒叙           com.jmu

         2、项目名称                            oa

         3、模块信息                            xxx

         4、功能顶层包                       service、dao、beans、vo 

         5、实现类  (有些功能包没有实现类)                             impl

         例: com.jmu.oa.xxx.dao.impl

       之所以要这样命名项目中的包,是为了保证项目中所用到的类具有全球唯一性。

        实体

        beans、entity、持久化对象po(Persistance Object)

       以上包中所存放的类,数据库中有其对应的表,一般有id 属性。

        vo:Value Object,值对象。一般用于类和页面之间传值

       dto:Data  Transter Object, 数据传输对象,一般用于类间传值。

     以上包中所存放的类,数据库中没有其对应的表,用于类和类之间、类和对象之间传值,一般没有id属性。因为它们不需要持久化。仅仅是用于在代码中进行数据传递。

    dao: Data Access Object 数据访问对象,增删改查

    三、代理环境的搭建

    public interface ISomeService {
     String doFirst();
     void doSecond();
    }
    

      

    public class SomeServiceImpl implements ISomeService{
    
        @Override
        public String doFirst() {
            // TODO Auto-generated method stub
            System.out.println("执行doFirst()方法");
            return "abcde";
        }
    
        @Override
        public void doSecond() {
            // TODO Auto-generated method stub
            System.out.println("执行doSecond()方法");
            
        }
    
    }
     1 public class MyTest {
     2 
     3     public static void main(String[] args) {
     4         // TODO Auto-generated method stub
     5         ISomeService service=new SomeServiceImpl();
     6         String result =service.doFirst();
     7         System.out.println("result="+result);
     8         service.doSecond();
     9     }
    10 
    11 }

    输出:

    执行doFirst()方法
    result=abcde
    执行doSecond()方法

    四、静态代理的实现

    静态代理:代理类在程序运行前已经定义好,其与目标类的关系在程序运行前已经确立。

    案例要求:

    要求输出大写的ABCD

     1 import com.jmu.service.ISomeService;
     2 import com.jmu.serviceImpl.SomeServiceImpl;
     3 //代理类
     4 public class SomeServiceProxy implements ISomeService{
     5 
     6     private ISomeService target;
     7 
     8     public SomeServiceProxy() {
     9         target = new SomeServiceImpl();
    10     }
    11 
    12     @Override
    13     public String doFirst() {
    14         //代理类调用目标方法
    15         String result=target.doFirst();
    16         //增强        
    17         return result.toUpperCase();
    18     }
    19 
    20     @Override
    21     public void doSecond() {
    22         // TODO Auto-generated method stub
    23         target.doSecond();
    24     }
    25 
    26 }

    输出:

    执行doFirst()方法
    result=ABCDE
    执行doSecond()方法
    

      

    (视频中的理解图)

    五、动态代理

    1、JDK动态代理

    使用JDK的Proxy动态代理,要求目标类必须实现接口,因为其底层的实现原理和静态代理一样。

    在之前基础上删除 SomeServiceProxy类,然后

     1 import java.lang.reflect.InvocationHandler;
     2 import java.lang.reflect.Method;
     3 import java.lang.reflect.Proxy;
     4 
     5 import com.jmu.service.ISomeService;
     6 import com.jmu.serviceImpl.SomeServiceImpl;
     7 
     8 public class MyTest {
     9 
    10     public static void main(String[] args) {
    11         // TODO Auto-generated method stub
    12         ISomeService target=new SomeServiceImpl();
    13         ISomeService service=(ISomeService) Proxy.newProxyInstance(
    14                 target.getClass().getClassLoader(),//目标类的类加载器
    15                 target.getClass().getInterfaces(), //目标类所实现的所有接口
    16                 new  InvocationHandler() {          //匿名内部类
    17                     //proxy:代理对象
    18                     //method:目标对象
    19                     //args:目标对象的参数列表
    20                     @Override
    21                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    22                         // TODO Auto-generated method stub
    23                         //调用目标方法
    24                         Object result = method.invoke(target, args);
    25                     
    26                         if (result!=null) {
    27                             result = ((String) result).toUpperCase();
    28                         }
    29                         return result;
    30                     }
    31                 });
    32         String result =service.doFirst();
    33         System.out.println("result="+result);
    34         service.doSecond();
    35     }
    36 
    37 }

    2、CGLIB动态代理

    对于无接口的类,要为其创建动态代理,就要用CGLIB来实现。CGLIB代理的生成原理是生成目标类的子类,而子类是增强过的,这个子类对象就是代理对象。所以,使用CGLIB生成动态代理,要求目标类能被继承,不能是final的类。

    对于有接口的类,以为其有子类,所以也会有CGLIB动态代理。

    首先,添加cglib包

    还涉及方法回调设计模式

    (1)无接口

    public class SomeService {
    
    
        public String doFirst() {
            // TODO Auto-generated method stub
            System.out.println("执行doFirst()方法");
            return "abcde";
        }
    
        
        public void doSecond() {
            // TODO Auto-generated method stub
            System.out.println("执行doSecond()方法");
            
        }
    
    }
     1 package com.jmu.factory;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 import com.jmu.service.SomeService;
     6 
     7 import net.sf.cglib.proxy.Enhancer;
     8 import net.sf.cglib.proxy.MethodInterceptor;
     9 import net.sf.cglib.proxy.MethodProxy;
    10 
    11 public class MyCglibFactory implements MethodInterceptor {
    12     private SomeService target;
    13 
    14     public MyCglibFactory() {
    15         target = new SomeService();
    16     }
    17 
    18     public SomeService myCglibCreator() {
    19         // 创建增强器对象
    20         Enhancer enhancer = new Enhancer();
    21         // 指定目标类,即父类
    22         enhancer.setSuperclass(SomeService.class);
    23         // 设置回调接口对象
    24         enhancer.setCallback(this);
    25         return (SomeService) enhancer.create();
    26     }
    27 
    28     // 回调方法
    29     @Override
    30     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    31         Object result = method.invoke(target, args);
    32         
    33         if (result!=null) {
    34             result = ((String) result).toUpperCase();
    35         }
    36         return result;
    37     }
    38 }
     1 package com.jmu.test;
     2 
     3 import com.jmu.factory.MyCglibFactory;
     4 import com.jmu.service.SomeService;
     5 
     6 public class MyTest {
     7 
     8     public static void main(String[] args) {
     9         // TODO Auto-generated method stub
    10         SomeService service=new MyCglibFactory().myCglibCreator();
    11         String result =service.doFirst();
    12         System.out.println("result="+result);
    13         service.doSecond();
    14     }
    15 
    16 }

    (2)有接口

    1 package com.jmu.service;
    2 //业务接口
    3 public interface ISomeService {
    4 //目标方法
    5  String doFirst();
    6  void doSecond();
    7 }
     1 package com.jmu.service;
     2 
     3 import com.jmu.service.ISomeService;
     4 //目标类
     5 public class SomeServiceImpl implements ISomeService{
     6 
     7     @Override
     8     public String doFirst() {
     9         // TODO Auto-generated method stub
    10         System.out.println("执行doFirst()方法");
    11         return "abcde";
    12     }
    13 
    14     @Override
    15     public void doSecond() {
    16         // TODO Auto-generated method stub
    17         System.out.println("执行doSecond()方法");
    18         
    19     }
    20 
    21 }
     1 package com.jmu.factory;
     2 
     3 import java.lang.reflect.Method;
     4 
     5 import com.jmu.service.ISomeService;
     6 import com.jmu.service.SomeServiceImpl;
     7 
     8 import net.sf.cglib.proxy.Enhancer;
     9 import net.sf.cglib.proxy.MethodInterceptor;
    10 import net.sf.cglib.proxy.MethodProxy;
    11 
    12 public class MyCglibFactory implements MethodInterceptor {
    13     private ISomeService target;
    14 
    15     public MyCglibFactory() {
    16         target = new SomeServiceImpl();
    17     }
    18 
    19     public ISomeService myCglibCreator() {
    20         // 创建增强器对象
    21         Enhancer enhancer = new Enhancer();
    22         // 指定目标类,即父类
    23         enhancer.setSuperclass(ISomeService.class);
    24         // 设置回调接口对象
    25         enhancer.setCallback(this);
    26         return (ISomeService) enhancer.create();
    27     }
    28 
    29     // 回调方法
    30     @Override
    31     public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
    32         Object result = method.invoke(target, args);
    33         
    34         if (result!=null) {
    35             result = ((String) result).toUpperCase();
    36         }
    37         return result;
    38     }
    39 }
     1 package com.jmu.test;
     2 
     3 import com.jmu.factory.MyCglibFactory;
     4 import com.jmu.service.ISomeService;
     5 
     6 public class MyTest {
     7 
     8     public static void main(String[] args) {
     9         // TODO Auto-generated method stub
    10         ISomeService service=new MyCglibFactory().myCglibCreator();
    11         String result =service.doFirst();
    12         System.out.println("result="+result);
    13         service.doSecond();
    14     }
    15 
    16 }
  • 相关阅读:
    vue前端使用JsonViewer进行json展示
    vue代理服务器proxy配置
    'vue-cli-service' 不是内部或外部命令,也不是可运行的程序 或批处理文件。
    Python中的高阶函数和内置高阶函数(abs,map,reduce,sorted,filter)
    Ant Design Vue 通过v-decorator实现数据绑定
    Vue脚手架(vue-cli)搭建和目录结构详解
    如何使用Postman从XML提取变量
    【已解决】Vue格式化js自动加上冒号和分号
    vue.js安装与搭建
    Python函数中如何返回多个值?
  • 原文地址:https://www.cnblogs.com/hoje/p/8060080.html
Copyright © 2011-2022 走看看