• 如何实现在已有代码之后添加逻辑之java动态代理


    在上篇博客中讨论到java的静态代理, 就是通过组合的方法,前提是委托类需要实现一个接口,代理类也实现这个这个 接口,从何组合两个类,让代理类给委托类添加功能!

    知道java的静态代理,我们又遇到一个问题,我们又遇到一个问题,是不是每个类要添加功能,都得重新写个类呢!怎么才能实现同样的代码,可以在其他类都能起作用!

    这就是java动态代理的内容,在java中通Proxy类好AnnotationHandler接口来实现动态代理,我先尝试自己写一个自己的动态代理!

    一.实现简单的自定义动态代(没考虑参数,接口) 只能称之为     伪java动态代理

    1、接口:

    public interface ICommonInterface {
       //nothing
    	public void addUser();
    	public void delete();
    }
    

     2、需要代理的类(委托类)

    /*
     * 自定义java动态代理
     * 这是一个委托类
     */
    public class DelegationClass implements ICommonInterface {
    
    	public  void addUser()
    	{
    		System.out.println("add user success");
    	}
    	
    	public  void delete()
    	{
    		System.out.println("delete user success");
    	}
    	
    }
    

     3.代理类

    import java.lang.reflect.InvocationTargetException;
    import java.lang.reflect.Method;
    
    
    public class ProxyClass {
    
    	//定义委托类对象(组合对象)
    	private Object target=null;
    	public ProxyClass(Object target)
    	{
    		this.target=target;  //构造方法初始化委托对象实例
    	}
    	
    	
    	public void invokeFunction(Method m) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException
    	{
    		System.out.println("before start.....");
    		m.invoke(target);
    	}
    	
    }
    

     4.测试类

    import java.lang.reflect.InvocationTargetException;
    
    public class Test {
    	public static void main(String [] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
    	{
    		//获取委托对象
    	    DelegationClass target=new DelegationClass();
    	    //获取代理对象
    	    ProxyClass pro=new ProxyClass(target);
    	    //传递委托对象调用方法,调用代理对象对应的方法实现
    	    pro.invokeFunction(target.getClass().getMethod("addUser"));
    	    pro.invokeFunction(target.getClass().getMethod("delete"));
    	}
    }
    
    结果:
    before start.....
    add user success
    before start.....
    delete user success
    

     我们可以看到实现的简单代理类,代理类没有涉及到接口,也没涉及到参数传递.....这些条件导致这个代理很好实现,现实中,我们得考虑接口,考虑参数 !


    我们来看看java怎么实现动态代理的:

    java中有两个类:InvocationHandler 和Proxy  其中Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现

    我们来看看实例:

    业务接口:

    public interface ICommonInterface {
       //nothing
    	public void addUser();
    	public void delete();
    }
    

     业务接口实现:

    public class DelegationClass implements ICommonInterface {
    
    	public  void addUser()
    	{
    		System.out.println("add user success");
    	}
    	
    	public  void delete()
    	{
    		System.out.println("delete user success");
    	}
    	
    }
    

     InvocationHandler实现,需要在接口方法调用前加入一部分其他逻辑

    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    public class Interceptor implements InvocationHandler {
    
    	//声明一个委托类的对象
    	private Object target=null;
    	public Interceptor(Object target)
    	{
    		this.target=target;
    	}	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    		// TODO Auto-generated method stub
    	    doBefore();
    	    method.invoke(target, args);
    		return null;
    	}
    	public void  doBefore()
    	{
    		System.out.println("start ...............");
    	}
    	
    }
    

    测试类:

    public class Test {
    	public static void main(String [] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException
    	{
    		//获取委托对象
    	    DelegationClass target=new DelegationClass();
    	    //获取InvocationHanlder的实例对象
    	    Interceptor inter=new Interceptor(target);
    	    //获取代理对象(实际上Proxy根据target的类加载器,接口和InvocationHandle生成一个类,再生成一个对象)
    	    ICommonInterface de= (ICommonInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),
    	    		target.getClass().getInterfaces(), inter);
    	    //测试这个对象
    	    System.out.println(de.getClass().getInterfaces()[0].getName());
    	    de.addUser();
    	    de.delete();
    	}
    }
    

    结果:

    com.test.proxy.javaproxy.ICommonInterface
    start ...............
    add user success
    start ...............
    delete user success

  • 相关阅读:
    20191024-6 Alpha发布用户使用报告
    【第三章】MySQL数据库的字段约束:数据完整性、主键、外键、非空、默认值、自增、唯一性
    【第六章】MySQL日志文件管理
    【第四章】MySQL数据库的基本操作:数据库、表的创建插入查看
    【第一章】MySQL数据概述
    【Linux运维】LNMP环境配置
    【Linux 运维】linux系统修改主机名
    【Linux 运维】linux系统查看版本信息
    【Linux 运维】Centos7初始化网络配置
    50、树中两个节点的公共祖先
  • 原文地址:https://www.cnblogs.com/fjsnail/p/3495817.html
Copyright © 2020-2023  润新知