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()+"\t"+g.getNumber()+"\t"+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());
        }
    }
}

 

 

posted @ 2021-08-18 20:38  伊万  阅读(179)  评论(0编辑  收藏  举报