Java动态代理

Posted 汤米先生

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java动态代理相关的知识,希望对你有一定的参考价值。

文章目录

一. 静态代理

1. 使用代理模式的作用

  1. 在原有功能的基础上增强功能。
  2. 控制访问,作为中介,不让二者直接访问。

2. 实现代理的方式

  1. 静态代理:代理类是自己手工实现的,自己创建的java类。
  2. 所要代理的目标类是确定的。
  3. 优点:简单实现,容易理解。
  4. 缺点:当目标类增加了,代理类要成倍的增加,导致代码类过多;
  5. 当你的接口功能改变,会影响众多的实现类。

3. 实现步骤

  1. 创建一个接口
  2. 创建类去实现接口
  3. 创建一个代理类,同样去实现接口。
  4. 创建一个功能类(main),调用代理类去在2中创建的类中获取想要的结果。

4. 实现代码

//1.创建一个接口

public interface Sell 
    float sell (int amount);


//2. 创建一个类去实现接
public class Factory implements Sell
    @Override
    public float sell(int amount) 
        return 85.0f;
    


//3.创建一个代理类同样去实现接口

public class Business implements Sell
    private  Factory factory = new Factory();

    public float sell(int amount) 

        float price = factory.sell(amount);
        price = price+25;
        return price;
    


//4. 主类去调用其他类,实现方法
public class ShopMain 
    public static void main(String[] args) 
        Business taobao = new Business();
        float price = taobao.sell(1);
        System.out.println("通过淘宝购买的价格为:"+price);
    


二. 动态代理

动态代理与静态代理相比,弥补静态代理的许多缺点,目标类即使很多,代理数也可以很少,当更改接口方法时也不会影响代理。

1. 介绍

在程序执行的过程中,使用jdk的反射机制,创建代理类对象,并动态的指定要代理目标类。
使用jdk的反射机制,创建对象的能力,创建的是代理类的对象。而不用你创建类文件,不用写java文件。
在程序执行时,调用jdk提供的方法才能创建代理的对象。

2. 实现步骤

  1. 创建接口,定义目标类要完成的功能。
  2. 创建目标类实现接口
  3. 创建InvocationHandler接口的实现类,在invoke方法中完成代理类的功能,
    3.1 调用目标方法
    3.2 增强 功能
  4. 使用Proxy类的静态方法,创建代理对象,并把返回值转为接口类型。

3. 反射机制代码实现

反射机制是通过method方法,来执行类中的某个方法。

package com.Interface;

public interface Service 
    public void sayHello(String name);



package com.Interface.Impl;

import com.Interface.Service;

public class ServiceImpl implements Service 
    @Override
    public void sayHello(String name) 
        System.out.println("你好"+name);
    


package com.Interface.Impl;

import com.Interface.Service;

public class ServiceImpl2 implements Service 
    @Override
    public void sayHello(String name) 
        System.out.println("你好呀,"+name);
    


package com.company;

import com.Interface.Impl.ServiceImpl;
import com.Interface.Impl.ServiceImpl2;
import com.Interface.Service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Main 

    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException 
	// write your code here
        Service service = new ServiceImpl();
        Service service2 = new ServiceImpl2();
  /*      service.sayHello("张三");
        service2.sayHello("李四");
*/

        Method sayHello = Service.class.getMethod("sayHello", String.class);
        Object ret = sayHello.invoke(service, "李四");
        sayHello.invoke(service2, "李四");
    


4. 动态代理代码实现

此处是调用了UsbKingFactory中的方法,但经过MysellHandler代理,在没有修改原来方法的基础上增强/增加了功能,这就是代理的精辟之处。

package com.zpx.factory;

import com.zpx.service.UsbSell;
//目标类
public class UsbKingFactory implements UsbSell 
    @Override
    public float sell(int amount) 
        //目标方法
        return 85.0f;
    


package com.zpx.handler;

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

public class MySellHandler implements InvocationHandler 
    //创建一个动态的目标对象
    private Object target = null;
    //得到动态的目标对象,传入谁,给谁创建代理。
    public MySellHandler(Object target)
        this.target=target;
    
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable 
        //创键目标对象代理
       Object res = null;

       res = method.invoke(target,args);

       //对目标对象进行加价。
        if (res!=null)
            float price = (float) res;
            price = price + 25;
            res = price;
        
        return res;
    


package com.zpx.service;
//目标接口
public interface UsbSell 
    float sell(int amount);



package com.zpx;

import com.zpx.factory.UsbKingFactory;
import com.zpx.handler.MySellHandler;
import com.zpx.service.UsbSell;

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

public class MainShop 
    public static void main(String[] args) 
        //1. 创建目标对象
        UsbSell factory = new UsbKingFactory();
        //2. 创建InvocaHandler对象
        InvocationHandler handler = new MySellHandler(factory);
        //3. 创建代理对象
        UsbSell proxy = (UsbSell) Proxy.newProxyInstance(factory.getClass().getClassLoader(),
                factory.getClass().getInterfaces(),
                handler);
        //4.通过代理执行方法。
        float price = proxy.sell(1);
        System.out.println("通过代理对象调用方法"+price);
    


以上是关于Java动态代理的主要内容,如果未能解决你的问题,请参考以下文章

Java反射反射的应用----JDK动态代理

Java重要技术(27)动态代理之查看代理对象的类型信息

java mybatis学习之$和#区别,mapper代理接口,动态SQL,在日志中输出mybatis的sql语句

动态代理与动态编译

JAVA动态代理

如何用Java动态代理实现AOP