Java教程

【设计模式】静态代理和动态代理

本文主要是介绍【设计模式】静态代理和动态代理,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1.什么是代理? 1.代购,中介,换ip,商家等等   使用代理模式的作用: 1.功能增强:在你原有的功能上,增加了额外的功能,新增加的功能,叫做功能增强 2.控制访问:代理类不让你访问目标,例如商家不让用户访问厂家   实现代理的方式

1.静态代理:

代理类是自己手工实现的,自己创建一个java类。同时你所要代理的

目标类是确定的。

特点:1)实现简单 2)容易理解 当项目中目标类和代理类很多之后,代理类数量过多 3)当目标类增加了,代理类可能也需要成倍的增加,代理类数量过多 4)当你的接口功能增加了,或者修改了,会影响众多的实现类,厂家类,代理都需要 修改,影响比较多。 例子:模拟用户购买U盘的行为 用户是客户端类 商家:代理,代理某个品牌的U盘 厂家:目标类 三者的关系:用户(客户端)-----商家(代理)---厂家(目标) 商家和厂家都是卖U盘的,他们完成的功能都是一致的,都是卖U盘的 实现步骤 1.创建一个接口,定义卖U盘的方法,表示你的厂家和商家做的事情 2.创建厂家类,实现1步骤的接口 3.创建商家,就是代理类,也需要实现1步骤中的接口 4.创建客户类,


测试用例:

UserService接口

package com.wang.pojo;

public interface UserService {
    public void add();
    public void delete();
    public void update();
    public void query();
}

UserService接口实现类UserServiceImpl

package com.wang.pojo;

public class UserServiceImpl implements UserService{

    @Override
    public void add() {
        System.out.println("增加了一个用户");
    }

    @Override
    public void delete() {
        System.out.println("删除了一个用户");
    }

    @Override
    public void update() {
        System.out.println("修改了一个用户");
    }

    @Override
    public void query() {
        System.out.println("查询了一个用户");
    }

}

UserService接口静态代理类

package com.wang.pojo;

public class UserSericeProxy implements UserService{
    private UserService service;

    public void setService(UserService service) {
        this.service = service;
    }

    @Override
    public void add() {
        beforeDoing();
        service.add();
        afterDoing();
    }

    @Override
    public void delete() {
        beforeDoing();
        service.delete();
        afterDoing();
    }

    @Override
    public void update() {
        beforeDoing();
        service.update();
        afterDoing();
    }

    @Override
    public void query() {
        beforeDoing();
        service.query();
        afterDoing();
    }
    private void beforeDoing(){
        System.out.println("代理对象方法执行前");
    }
    private void afterDoing(){
        System.out.println("代理对象方法执行后");
    }
}

 

    2.动态代理: 在静态代理中目标类很多时候,可以使用动态代理,避免静态代理的缺点。 动态代理中目标类即使很多,代理类数量可以很少。 当你修改了接口中的方法时,不会影响代理类     动态代理: 在程序执行过程中,使用jdk的反射机制,创建代理类对象,并动态指定要代理对象。 换句话说:动态代理是一种创建java对象的能力,让我不用创建taobao类就能创建 代理类对象。   在java中,要创建对象: 1.创建类文件,java文件编译为class 2.使用构造方法,创建类的对象     什么是动态代理? 使用jdk的反射机制,创建对象的能力,创建的时代理类的对象。而不是创建类文件, 不用写。   动态: 在程序执行时,调用jdk的方法才能创建代理类的对象    

 

 

    动态代理方式: 第一种,JDk动态代理(理解):使用java反射包中的类和接口实现动态代理的功能 反射包 java.lang.reflect,里面有三各类:InvocationHandler,Method,Proxy.   第二种,通过CGLB动态代理(了解):第三方的一个工具库,创建代理对象。 cglib的原理时继承,cglib通过继承目标类,创建它的子类,在子类中重写 父类中同名的方法,实现功能的修改   因为cglib是继承,重写方法,所以要求目标类不能是final,方法也不能是final. cglib要求目标类比较宽松,只要能继承就可以了,cglib在很多框架中都可以使用 ,比如mybatis,spring框架中都有使用。   cgLib代理     jdK动态代理 1.反射,Method类,表示方法,类中的方法。通过Method可以执行某个方法。 2.jdk动态代理的实现 反射包 java.lang.reflect,里面有三个类: InvocationHandler,Method,Proxy. 1)InvocationHandler(调用处理器) 接口:就一个方法invoke() invoke():表示代理对象要执行的功能代码。你的代理类要完成的功能 就写在invoke()中 代理类完成的功能: 1.调用目标方法,执行目标方法的功能 2.功能增强,在目标方法调用时,增加功能    
public Object invoke(Object proxy, Method method, Object[] args) //Object proxy:JDK创建的代理对象,无需赋值。 //Method method:目标类中的方法,jdk提供method对象的 // Object[] args:目标类中的方法参数

 

2)Method类:表示方法的,确切的说就是目标类中的方法 作用:通过Method可以执行某个目标类的方法,Method.invoke(); method.invoke(目标对象,方法的参数); 3)Proxy类:创建对象都是new 类的构造方法() 现在是使用Proxy类的方法,代表new的使用。 方法:静态方法 newProxyInstance() 作用是:创建代理对象,等同于静态代理中的 TaoBao tb=new TaoBao(); public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) //ClassLoader loader 类加载器,负责像内存中加载对象的, 使用反射 //获取对象的ClassLoader 举例 类a a.getClass().getClassLoader() //目标对象的类加载器 //Class<?>[] interfaces 目标对象所实现的接口,也是反射获取的 //InvocationHandler h:我们自己写的,代理类要完成的功能 //返回值 就是代理对象。     实现动态代理的步骤
//1.创建接口,定义目标类要完成的功能
//2.创建目标类实现接口
//3.创建IncovateHandler接口的实现类,在invoke方法中完成代理类的功能
//功能有二:1.调用目标方法  2.增加功能
//4.使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型
UsbShell proxy=(UsbShell)Proxy.newProxyInstance(UsbKingFactory.class.getClassLoader(),factory.getClass().getInterfaces(),handler );
//com.sun.proxy.$Proxy0
//通过代理对象执行方法调用,执行handler
//proxy.sell(1),此时执行的是handler中的incoke方法

 

 


  动态代理能做什么? 可以在不改变原来目标方法功能的前提下,可以在代理中增强自己的功能代理. 程序开发中的意义: 比如,你所在的项目中,有一个功能是其他人(公司的其他部门,其他小组的人)写好的, 你可以使用,
GoNong.class,
GoNong gn=new GoNong(),
gn.print();
你发现这个功能,现在还缺点,不能完全满足我项目的需求,我需要在gn.print()执行后,需要自己在增加代码,用代理实现gn.print()调用时,增加自己代理,而不用改原来的GoNong文件。

测试用例

代理类处理程序接口InvocationHandler实现类

package com.wang.pojo;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;


//万能的invocationHandler实现类
public class MyInvocationHandler implements InvocationHandler {
    //被代理对象
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //处理代理实例
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //可以在此添加额外功能
        /*
         * 额外功能
         * */

        //
        see();
        return  method.invoke(target,args);
    }
    private void see(){
        System.out.println("房产中介参与租房业务");
    }
}

 

万能动态代理类实现模板

package com.wang.staticProxy.demo04;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

//万能的invocationHandler实现类
public class MyInvocationHandler implements InvocationHandler {
    //被代理对象
    private Object target;

    public void setTarget(Object target) {
        this.target = target;
    }

    //生成代理对象
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this);
    }
    //处理代理实例
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //可以在此添加额外功能
        /*
        * 额外功能
        * */

        //
        someMethod();
      Object o=method.invoke(target,args);
     return 0;
}
 private void someMethod(){ *** } }

推荐的动态代理相关文章

  • Java 动态代理详解

 

这篇关于【设计模式】静态代理和动态代理的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!