zoukankan      html  css  js  c++  java
  • Java静态代理和动态代理

    Java代理简介

    Java中的代理通常是为某个对象提供一种代理机制,从而控制对这个对象不能直接进行访问,代理不是技术而是一种设计模式。

    代理机制能够实现对某个对象业务功能实现的隐藏,代理程序可以对目标对象进行渲染以及对使用对象者进行有效控制,代理可以被看做是AOP模式的实现。

    代理实现中可以分为以下角色:

    抽象接口:声明真实对象和代理对象的共同接口

    代理角色(代理实现者):其中主要包含了被代理对象

    真实角色(被代理对象):客户最终要引用目标对象

    静态代理实现

    1. 代理角色和真实角色拥有共同的抽象接口
    2. 一个真实对象对应一个代理角色
    3. 真实角色实现必需存在,在代理对象中被固定不变
    4. 设计实现简单清晰,会产生更多的类

     

    动态代理实现

    1. 代理类的代理实现代码被固定下来,不会因为业务的逐渐增长的改变
    2. 在程序运行时才确定被代理对象类型
    3. 实现AOP编程更加灵活,这是静态代理无法实现的
    4. 解耦,如果用在web业务下,可以实现数据层和业务层的

     

    InvocationHandler组件

    InvocationHandlerjava.lang.reflect反射包下的实现动态代理的规范接口,通常自定义实现的动态代理类必须实现此接口。

    Object invoke(Object obj,Method method,Object[] args)

    参数obj是动态代理实现的实例

    参数method是目标被代理对象的业务方法

    参数args是传递给目标方法的所有参数

    Object是目标方法的返回值,如果没有返回值则返回null对象

     

    Proxy组件

    java.lang.reflect.Proxy类提供了用于创建动态代理类和实例的静态方法,它还是由这些方法创建的所有动态代理类的超类

     

    public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler handler)

    参数loader是被代理类的类加载器

    参数interfaces是被代理类的所有父接口

    参数handler是实现动态代理类的实例

     

    静态代理:

     

    package com.xzit.entity;
    /**
     * 客户实体类
     * @author Administrator
     *
     */
    public class Client {
    
        private String name; // 客户姓名
    
        private boolean isVip; // 是否是VIP客户
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public boolean isVip() {
            return isVip;
        }
    
        public void setVip(boolean isVip) {
            this.isVip = isVip;
        }
    }

     

    package com.xzit.entity;
    /**
     * 商品实体类
     * @author Administrator
     *
     */
    public class Goods {
    
        private String number;// 商品编号
        private String name;// 商品名称
        private Double price; // 商品单价
    
        public String getNumber() {
            return number;
        }
        public void setNumber(String number) {
            this.number = number;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Double getPrice() {
            return price;
        }
        public void setPrice(Double price) {
            this.price = price;
        }
    
        public Goods() {
    
        }
    
        public Goods(String number, String name, Double price) {
            this.number = number;
            this.name = name;
            this.price = price;
        }
    }
    package com.xzit.entity;
    
    import com.xzit.db.DataBase;
    import com.xzit.interfaces.IGoods;
    
    import java.util.List;
    
    /**
     * 生产商
     */
    public class Producer implements IGoods {
    
        @Override
        public List<Goods> producerGoodsList() {
    
            return DataBase.GOODSLIST;
        }
    }
    package com.xzit.interfaces;
    
    import com.xzit.entity.Goods;
    
    import java.util.List;
    
    /**
     * 提供产品列表的接口
     * 代理实现者和被代理对象都应该实现此接口
     */
    public interface IGoods {
    
        /**
         * 提供产品的方法
         * @return
         */
        List<Goods> producerGoodsList();
    
    }
    package com.xzit.aop;
    
    import com.xzit.entity.Client;
    import com.xzit.entity.Goods;
    import com.xzit.entity.Producer;
    import com.xzit.interfaces.IGoods;
    
    import java.util.List;
    
    public class ProducerProxy implements IGoods {
    
        private Producer producer;  //被代理对象
        private Client client;      //购买对象
        @Override
        public List<Goods> producerGoodsList() {
            boolean bool = validateIsVip();
            if (bool){
                List<Goods> goodsList =  producer.producerGoodsList();
                for (Goods g:goodsList){
                    g.setPrice(g.getPrice()*0.85);
                }
                return goodsList;
            }
            return producer.producerGoodsList();
        }
    
        public void setProducer(Producer producer) {
            this.producer = producer;
        }
    
        public void setClient(Client client) {
            this.client = client;
        }
    
        private boolean validateIsVip(){
    
            if (client.isVip())
                return true;
                return false;
        }
    
    }
    package com.xzit.proxy;
    
    import com.xzit.aop.ProducerProxy;
    import com.xzit.entity.Client;
    import com.xzit.entity.Goods;
    import com.xzit.entity.Producer;
    
    
    import java.util.List;
    import java.util.Scanner;
    
    public class TestStaticProxy {
        public static void main(String[] args) {
    
            Scanner in = new Scanner(System.in);
            ProducerProxy proxy = new ProducerProxy();  //代理实现者
            proxy.setProducer(new Producer());
    
            System.out.println("输入客户姓名");
            String name = in.next();
    
            System.out.println("您是VIP请输入1,否则输入0");
            int isVip = in.nextInt();
            boolean bool = isVip == 1?true:false;
            Client c = new Client();
            c.setName(name);
            c.setVip(bool);
    
            proxy.setClient(c);
    
            List<Goods> goodsList = proxy.producerGoodsList();  //调用代理实现方法
    
            for (Goods g:goodsList){
    
                System.out.println(g.getName()+"	"+g.getNumber()+"	"+g.getPrice());
            }
    
        }
    }
    package com.xzit.db;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import com.xzit.entity.Department;
    import com.xzit.entity.Employee;
    import com.xzit.entity.Goods;
    
    public class DataBase {
    
        public static final List<Department> DEPLIST = new ArrayList<Department>();
        public static final List<Employee> EMPLIST = new ArrayList<Employee>();
        public static final List<Goods> GOODSLIST = new ArrayList<Goods>();
    
        static{
            DEPLIST.add(new Department("dep100","事业部"));
            DEPLIST.add(new Department("dep200","策划部"));
            DEPLIST.add(new Department("dep300","市场部"));
            DEPLIST.add(new Department("dep400","人事部"));
            DEPLIST.add(new Department("dep500","研发部"));
            DEPLIST.add(new Department("dep600","测试部"));
    
            EMPLIST.add(new Employee("任我行","男","黑木崖"));
            EMPLIST.add(new Employee("任盈盈","女","黑木崖"));
            EMPLIST.add(new Employee("令狐冲","男","华山"));
            EMPLIST.add(new Employee("岳不群","男","华山"));
            EMPLIST.add(new Employee("丁春秋","男","南海"));
    
            GOODSLIST.add(new Goods("goods100","加热器",123.50));
            GOODSLIST.add(new Goods("goods200","胜利羽毛球lark4",54.00));
            GOODSLIST.add(new Goods("goods300","联想笔记本T450",8900.50));
            GOODSLIST.add(new Goods("goods400","小米麦克风",99.50));
    
    
        }
    }

    ---------------------------------------------------------分割线---------------------------------------------------------------

    动态代理:

    package com.xzit.entity;
    /**
     * 部门信息实体类
     * @author Administrator
     *
     */
    public class Department {
    
        private String number;// 部门编号
    
        private String name;// 部门名称
    
        public String getNumber() {
            return number;
        }
    
        public void setNumber(String number) {
            this.number = number;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Department() {
    
        }
    
        public Department(String number, String name) {
            this.number = number;
            this.name = name;
        }
    }
    package com.xzit.entity;
    /**
     * 员工实体类
     * @author Administrator
     *
     */
    public class Employee {
    
        private String name;
        private String sex;
        private String address;
    
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
    
        /**
         * 无参构造器
         */
        public Employee() {
    
        }
    
        /**
         * 有参构造器
         * @param name
         * @param sex
         * @param address
         */
        public Employee(String name, String sex, String address) {
            this.name = name;
            this.sex = sex;
            this.address = address;
        }
    }
    package com.xzit.interfaces;
    
    import java.util.List;
    
    public interface IObject<T> {
    
        /**
         * 查找目标数据列表
         * @return
         */
        List<T> findList();
    }
    package com.xzit.interfaces;
    
    import com.xzit.db.DataBase;
    
    import java.util.List;
    
    public class DepartmentDaoImp<T> implements IObject<T>{
        @Override
        public List<T> findList() {
            System.out.println("获取部门列表");
            return (List<T>) DataBase.DEPLIST;
        }
    }
    package com.xzit.interfaces;
    
    import com.xzit.db.DataBase;
    
    import java.util.List;
    
    public class EmployeeDaoImp<T> implements IObject<T>{
        @Override
        public List<T> findList() {
            System.out.println("获取员工列表");
            return (List<T>) DataBase.EMPLIST;
        }
    }
    package com.xzit.aop;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    
    public class DynInvoke implements InvocationHandler {
    
        private Object target;  //被代理的对象
        /**
         * 重写实现动态代理的invoke方法
         * @param proxy
         * @param arg1
         * @param arg2
         * @return
         * @throws Throwable
         */
        @Override
        public Object invoke(Object proxy, Method arg1, Object[] arg2) throws Throwable {
    
            System.out.println("动态代理方法");
            Object obj = arg1.invoke(target,arg2);
            return obj;
        }
    
        public void setTarget(Object target){
            this.target = target;
        }
    }
    package com.xzit.proxy;
    
    import com.xzit.aop.DynInvoke;
    import com.xzit.entity.Department;
    
    import com.xzit.entity.Employee;
    import com.xzit.interfaces.DepartmentDaoImp;
    import com.xzit.interfaces.EmployeeDaoImp;
    import com.xzit.interfaces.IObject;
    
    import java.lang.reflect.Proxy;
    import java.util.List;
    
    public class TestDynProxy {
        /**
         * 动态代理测试
         * @param args
         */
        public static void main(String[] args) {
    
            DynInvoke dynInvoke = new DynInvoke();   //创建动态代理对象
            DepartmentDaoImp<Department> depDao = new DepartmentDaoImp<Department>();   //创建被代理的目标对象
            EmployeeDaoImp<Employee> empDao = new EmployeeDaoImp<Employee>();
            dynInvoke.setTarget(depDao);    //设置被代理对象
            dynInvoke.setTarget(empDao);    //设置被代理对象
            Class [] classes = depDao.getClass().getInterfaces();   //获取所有被代理对象的父接口数组
    
            IObject iObject = (IObject) Proxy.newProxyInstance(empDao.getClass().getClassLoader(),classes,dynInvoke);   //获取代理类实例
    
            List<Employee> depList = iObject.findList();  //调用目标方法
    
            for (Employee dep:depList){
                System.out.println(dep.getName());
            }
        }
    }

     

  • 相关阅读:
    印度出差之一
    印度出差疯狂的鸡翅
    GET和POST两种基本请求方法的区别
    对sleep和wait的理解
    Jquery 鼠标滑过时改变元素透明度的动画效果
    记忆里的科比
    New Features Summary Of Sybase® PowerDesigner® 15.0 For Windows[PD15新功能特征摘要]
    WF工作流接口规范
    Foxmail安装文件夹的整体转移(收集)
    c# vs2005 多线程中调用窗体控件 (摘)
  • 原文地址:https://www.cnblogs.com/zengyu1234/p/15158708.html
Copyright © 2011-2022 走看看