• JDK动态代理


    在java的java.lang.reflect包下面提供了一个Proxy类和一个invocationHander接口,通过这个类和接口就可以生成JDK动态代理类和动态代理对象。

    首先来看一下Proxy类,Proxy 提供用于创建动态代理类和代理对象的静态方法, 它也是所有动态代理类的父类。它只有一个构造方法:

     

    Proxy 提供了两个方法来创建动态代理类和动态代理实例:

     

    然后invocationHander是一个接口,每个代理实例都具有一个关联的调用处理程序。对代理实例调用方法时,将对方法调用进行编码并将其指派到它的调用处理程序的 invoke 方法。 


    关于这些其实了解下就好了,现在通过代码来实现java的动态代理。注意的是:java动态代理只能代理实现了同一个接口的类,cglib可以代理同一个类,具体的这个内容我回来整理spring框架的时候再做整理。

    package linkin;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class Linkin
    {
    	public static void main(String[] args)
    	{
    		Class proxyClass = Proxy.getProxyClass(Linkin.class.getClassLoader(), new Class[] { Linkin1.class });
    		//如果这里直接一步传入了InvocationHandler,那么前一个参数不能在动态传入,一定要写成数组形式
    		Linkin1 linkin = (Linkin1) Proxy.newProxyInstance(Linkin.class.getClassLoader(), new Class[] { Linkin1.class }, new InvocationHandler()
    		{
    			@Override
    			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    			{
    				// TODO Auto-generated method stub
    				return null;
    			}
    		});
    		System.out.println(proxyClass);
    		System.out.println(linkin.getClass());
    	}
    
    }
    
    //这里定义这个接口,统一为这个接口来跑代理
    interface Linkin1
    {
    
    }
    

    java的动态代理主要是用来实现AOP(面向切面编程),下面通过代码来演示如何AOP编程。

    package linkin;
    
    import java.lang.reflect.InvocationHandler;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    
    public class Linkin implements Person
    {
    	public static void main(String[] args)
    	{
    		//原始对象和代理对象实现了同一个接口,也就是说通过同一个接口来为原始对象创建了一个代理对象,代理对象可以执行原始对象的所有的方法,而且在原来的
    		//方法上还加入了通用的一系列操作
    		Linkin linkin = new Linkin();//原始的对象
    		Person linkinProxy = (Person) ProxyFactory.getProxy(linkin);//被代理的对象
    		linkin.sayInfo("这里是原始的对象的方法...");
    		System.out.println("===============");
    		linkinProxy.sayInfo("这里是代理对象的方法");
    	}
    
    	@Override
    	public void sayInfo(String str)
    	{
    		System.out.println("仰天大笑出门去..."+str);
    	}
    
    	@Override
    	public void test()
    	{
    		System.out.println("我辈岂是蓬蒿人...");
    	}
    
    }
    
    //这里定义这个接口,统一为这个接口来跑代理
    interface Person
    {
    	//这里定义2个方法用来测试
    	void sayInfo(String str);
    	void test();
    }
    
    //定义通用的类,里面模拟一些通用方法
    class LinkinUtil
    {
    	public void test()
    	{
    		System.out.println("这里是第一个通用方法。。。");
    	}
    	public void test1()
    	{
    		System.out.println("这里是第2个通用方法。。。");
    	}
    }
    
    //这里是InvocationHandler的实现类,这个才是重点
    class LinkinInvocationHandler implements InvocationHandler
    {
    	//这里把这个要被代理的对象放进来
    	private Object taget;
    	
    	public LinkinInvocationHandler()
    	{
    		
    	}
    	//在给一个带这个参数的构造器好了
    	public LinkinInvocationHandler(Object taget)
    	{
    		this.taget = taget;
    	}
    
    	public Object getTaget()
    	{
    		return taget;
    	}
    
    	public void setTaget(Object taget)
    	{
    		this.taget = taget;
    	}
    
    	@Override
    	//执行动态代理对象的所有的方法时,都变成了这个invoke方法。
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    	{
    		LinkinUtil linkinUtil = new LinkinUtil();
    		linkinUtil.test();
    		Object result = method.invoke(taget, args);
    		linkinUtil.test1();
    		return result;
    	}
    	
    }
    
    //定义个工厂,用来获得每一个代理对象
    class ProxyFactory
    {
    	public static Object getProxy(Object target)
    	{
    		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), 
    				new LinkinInvocationHandler(target));
    	}
    }
    



  • 相关阅读:
    springboot的build.gradle增加阿里仓库地址以及eclipse增加lombok
    mqttfx无法选择证书
    EMQX源码编译过程
    新环境chart包helmlint校验
    安装rebar3
    Ubuntu16.04下,erlang安装和rabbitmq安装步骤
    UTF-8,GBK,ANSI之间的关系和区别
    write命令
    bunzip2命令
    bzip2命令
  • 原文地址:https://www.cnblogs.com/LinkinPark/p/5233120.html
Copyright © 2020-2023  润新知