java中的proxy代理简单说明,以及静态代理和动态代理的简单代码示例

作者: admin 分类: JAVA 发布时间: 2019-06-21 13:19  阅读: 228 views

学习RPC的过程中,有用到java动态代理,所以这里简单整理下,方便日后查阅:

 

代理是一种模式,提供了对目标对象的间接访问方式,即通过代理访问目标对象。如此便于在目标实现的基础上增加额外的功能操作,前拦截,后拦截等,以满足自身的业务需求,同时代理模式便于扩展目标对象功能的特点。

动态代理特点:比较灵活,可以在运行的时候才切入改变类的方法,而不需要预先定义它。

场景: 权限控制、方法响应时间统计等。不需要改动具体的实现方法,而是通过代理在执行前后做处理。RPC、AOP就是应用了动态代理。

 

动态代理中有两个重要的方法:

1.实现InvocationHandler的invoke方法生成proxy实例
Object invoke(Object proxy, Method method, Object[] args) throws Throwable
三个参数的具体意思:
proxy:生成的代理类对象
method:被代理类的某个具体方法
arg0:实现方法的具体参数

2.动态生成代理类
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
loader 类加载器,被代理对象的类加载器
interfaces 代理对象实现的接口
h  代理实例

 

代码示例 – 静态代理

package com.chl.proxy;

/**
 * 静态代理模式,简单示例
 * 代理模式优点:
	职责清晰 真实角色只需关注业务逻辑的实现,非业务逻辑部分,后期通过代理类完成即可。
	高扩展性 不管真实角色如何变化,由于接口是固定的,代理类无需做任何改动。
 * @author chenhailong
 *
 */
public class StaticProxyText {

	public static void main(String[] args) {
		employeeA a = new employeeA("小王");
		employeeB b = new employeeB(a);
		//b员工做代理,实际是a在做事情
		b.doSomething();
	}
}

/**
 * 通用员工行为
 */
interface Common {
	void doSomething();
}

/**
 * a员工
 */
class employeeA implements Common {

	private String name;

	employeeA(String name) {
		this.name = name;
	}

	@Override
	public void doSomething() {
		System.out.println("exec:" + name);
	}

}

/**
 * b员工
 */
class employeeB implements Common {

	private Common com;

	employeeB(Common com) {
		this.com = com;
	}

	@Override
	public void doSomething() {
		com.doSomething();
	}

}

代码示例 – 动态代理

package com.chl.proxy;

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

/**
 * 动态代理实现
 * 通过实现InvocationHandler接口达到目的
 * 代理对象无需实现接口,免去了编写很多代理类的烦恼,同时接口增加方法也无需再维护目标对象和代理对象,只需在事件处理器中添加对方法的判断即可
 * @author chenhailong
 */
public class DynamicProxyText {

	public static void main(String[] args) {
		//被代理对象
		elephant el = new elephant();
		//中介类
		landAnimals la = new landAnimals(el);
		//类加载器
		ClassLoader loader = el.getClass().getClassLoader();
		//代理类一
		animals a = (animals)Proxy.newProxyInstance(loader, el.getClass().getInterfaces(), la);
		a.growUpTime();
		
		//代理类二
		animals b = vegetarianAnimals.getInstance(animals.class);
		b.growUpTime();
	}
}

/**
 * 通用动物操作
 */
interface animals{
	void growUpTime();
}

/**
 * 大象的成长
 */
class elephant implements animals{
	
	@Override
	public void growUpTime() {
		try {
			Thread.sleep(5 * 1000l);
			System.out.println("after 5 s,elephant is getting bigger !");
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

/**
 * 代理为陆地动物
 */
class landAnimals implements InvocationHandler{
	
	private animals als ;
	
	landAnimals(animals als){
		this.als = als;
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		System.out.println("before growup--!"+ System.currentTimeMillis());
		method.invoke(als, args);
		System.out.println("after  growup--!"+ System.currentTimeMillis());
		return null;
	}
}

/**
 * 素食动物
 */
class vegetarianAnimals{
	
	static InvocationHandler handler = new InvocationHandler() {
		@Override
		public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
			//获取proxy的接口类
			System.out.println(proxy.getClass().getInterfaces()[0].getName());
			System.out.println("before eat--!"+ System.currentTimeMillis());
			method.invoke(new elephant(), args);
			System.out.println("after  eat--!"+ System.currentTimeMillis());
			return null;
		}
	};
	
	@SuppressWarnings("unchecked")
	static <T> T getInstance(Class<T> cls) {
		return (T)Proxy.newProxyInstance(cls.getClassLoader(), new Class[]{cls}, handler);
	}
}

 


   原创文章,转载请标明本文链接: java中的proxy代理简单说明,以及静态代理和动态代理的简单代码示例

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!

发表评论

电子邮件地址不会被公开。 必填项已用*标注

更多阅读