java 代理的使用


Proxy(代理)  AOP(面向切面编程)
a)	为程序中具有多个相同接口的目标类各增加一些系统功能.例如.异常处理,日志,计算方法的运行时间.事物管理,等待.
b)	AOP系统中存在交叉业务(安全,事物,日志),每个交叉业务要贯穿系统中的每个模块,代理就是实现AOP功能的核心技术和关键技术
c)	动态代理.JVM可以在运行期动态的生成出类的字节码,这种动态生成的类用作代理,
d)	JVM生成的动态类必须实现一个或者多个接口,所以JVM生成的动态类只能用作具有相同接口目标类的代理。
e)	CGLIB库可以动态生成没有接口类的子类,一个类的子类也可以用作该类的代理,所以使用CGLIB也可以实现代理。



package com.enhance.proxy;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

/**
 * 使用代理创建对象 并获取对象的各种属性
 * InvocationHandler 
 * Object 只将 hashCode toString equals() 委托给 InvocationHandler 处理,其他的 方法没有委托给InvocationHandler 处理
 */
public class ProxyTest {
	/**
	 * @param args
	 * @throws Exception 
	 */
	public static void main(String[] args) throws Exception{
		// TODO Auto-generated method stub
		Class clazzProxy=Proxy.getProxyClass(Collection.class.getClassLoader(),Collection.class);
		System.out.println(clazzProxy.getName());
		System.out.println("---------begin constructor list---------");
		Constructor[] constructors=clazzProxy.getConstructors();
		for (Constructor constructor : constructors) {
			String name=constructor.getName();
			StringBuilder sbr=new StringBuilder(name);
			sbr.append('(');
			Class[] clazzParams=constructor.getParameterTypes();
			for (Class clazzParam : clazzParams) {
				sbr.append(clazzParam.getName()).append(',');
			}
			if(clazzParams!=null && clazzParams.length>0)
				sbr.deleteCharAt(sbr.length()-1);
			sbr.append(')');
			System.out.println(sbr.toString());
		}
		
		System.out.println("---------begin Method list---------");
		Method[] methods=clazzProxy.getMethods();
		for (Method method : methods) {
			String name=method.getName();
			StringBuilder sbr=new StringBuilder(name);
			sbr.append('(');
			Class[] clazzParams=method.getParameterTypes();
			for (Class clazzParam : clazzParams) {
				sbr.append(clazzParam.getName()).append(',');
			}
			if(clazzParams!=null && clazzParams.length>0)
				sbr.deleteCharAt(sbr.length()-1);
			sbr.append(')');
			System.out.println(sbr.toString());
		}

		System.out.println("---------begin Create Object ---------");
		
		//第一种写法
		Constructor con=clazzProxy.getConstructor(InvocationHandler.class);
		
		class MyInvocationHandler implements InvocationHandler{

			@Override
			public Object invoke(Object proxy, Method method, Object[] args)
					throws Throwable {
				// TODO Auto-generated method stub
				return null;
			}
		}
		
	  Collection poxy1=(Collection)con.newInstance(new MyInvocationHandler());
	 
	  
	  System.out.println(poxy1);
	  System.out.println(poxy1.toString());//对象不为空,但是 tostring()返回的是null  是因为  invoke返回的是null 所以就是null.
	  poxy1.clear();  //能成功调用
	 // poxy1.size();   //不能成功调用 NullException 原因 就是 上面的 InvocationHandler 的invoke 返回的是 null ,而 size 要返回的是int ,无法将null 转换成 int类型 所以就异常了
	  
	  //第二种写法
	  Collection poxy2=(Collection)con.newInstance(new InvocationHandler(){
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			// TODO Auto-generated method stub
			return null;
		}
	  });
	  
	  
	  //第三种写法 
	  Collection proxy3=(Collection)Proxy.newProxyInstance(
			  Collection.class.getClassLoader(),
			  new Class[]{Collection.class}, 
			  new InvocationHandler(){
				ArrayList target=new ArrayList();
				@Override
				public Object invoke(Object proxy, Method method, Object[] args)
						throws Throwable {
					//使用代理  来获取方法执行的时间 
					//或者 使用过滤器 来过滤  用户的非法内容 
					//或者 加入日志  加入事务 等等
					long stime=System.currentTimeMillis();
					Thread.sleep(10);
					Object retVal=method.invoke(target, args);
					long etime=System.currentTimeMillis();
					System.out.println(method.getName()+" runing time is "+(etime-stime));
					return retVal;
				}
			  });
	  Object obj= proxy3.add("zxx");
	  System.out.println("returnVal :"+obj);
	  proxy3.add("lhm");
	  proxy3.add("bxd");
	  System.out.println(proxy3.size());
	  
	  //接下来 将 上面的方法 抽取一个公共方法.
	}
	
	
	
}


简单的代理

package com.enhance.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collection;

public class ProxyUtil {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		final ArrayList list=new ArrayList();
		Collection proxy=(Collection)getProxy(list, new MyAdvice());
		proxy.add("zxx");
		proxy.add("lhm");
		proxy.add("bxd");
		System.out.println(proxy.size());
	}
	
	public static Object getProxy(final Object target,final Advice advice){
		Object proxy=Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						advice.beforeMethod(method);
						Object val=method.invoke(target, args);
						advice.afterMethod(method);
						return val;
					}
				});
		
		return proxy;
	}
	

}


package com.enhance.proxy;

import java.lang.reflect.Method;

public interface Advice {
	void beforeMethod(Method method);  //方法之前运行的代码
	void afterMethod(Method method);	//方法之后运行的嗲吗
	void exceptionMethod(Method method);	//方法异常运行的代码
	void beforeAfterMethod(Method method);//方法前后运行的代码
}
//------------------------------------------
package com.enhance.proxy;

import java.lang.reflect.Method;

public class MyAdvice implements Advice{

	long etime=0;
	long stime=0;
	@Override
	public void beforeMethod(Method method) {
		// TODO Auto-generated method stub
		System.out.println("开始学习啦!");
		stime=System.currentTimeMillis();
	}

	@Override
	public void afterMethod(Method method) {
		// TODO Auto-generated method stub
		System.out.println("学习结束了!");
		etime=System.currentTimeMillis();
		System.out.println(method.getName()+" runing time is "+(etime-stime));
	}

	@Override
	public void exceptionMethod(Method method) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void beforeAfterMethod(Method method) {
		// TODO Auto-generated method stub
		
	}

	
}


//mini AOPFreamework


package com.enhance.proxy.aopfreamwork;

import java.io.InputStream;

public class AopFrameworkTest {
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		InputStream ips=AopFrameworkTest.class.getResourceAsStream("config.properties");
		Object bean=new BeanFactory(ips).getBean("xxx");
		System.out.println(bean.getClass().getName());
	}

}




package com.enhance.proxy.aopfreamwork;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.enhance.proxy.Advice;

public class BeanFactory {

	private Properties props=new Properties();

	public BeanFactory(InputStream ips) {
		try {
			props.load(ips);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public Object getBean(String name){
		String className=props.getProperty(name);
		Object bean=null;
		try {
			Class clazz=Class.forName(className);
			bean=clazz.newInstance();
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		if(bean instanceof ProxyFactoryBean){
			ProxyFactoryBean proxyBean=((ProxyFactoryBean)bean);
			Advice advice=null;
			Object target=null;
			try {
				advice=(Advice)Class.forName(props.getProperty(name+".advice")).newInstance();
				target = Class.forName(props.getProperty(name+".target")).newInstance();
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			proxyBean.setAdvice(advice);
			proxyBean.setTarget(target);
			Object proxy=proxyBean.getProxy();
			return proxy;
		}
		return bean;
		
		
	}
	
	
}



package com.enhance.proxy.aopfreamwork;

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

import com.enhance.proxy.Advice;

public class ProxyFactoryBean {

	private Advice advice;
	private Object target;
	public Object getProxy() {
		Object proxy=Proxy.newProxyInstance(
				target.getClass().getClassLoader(), 
				target.getClass().getInterfaces(), 
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						advice.beforeMethod(method);
						Object val=method.invoke(target, args);
						advice.afterMethod(method);
						return val;
					}
				});
		
		return proxy;
	}
	
	public Advice getAdvice() {
		return advice;
	}
	public void setAdvice(Advice advice) {
		this.advice = advice;
	}
	public Object getTarget() {
		return target;
	}
	public void setTarget(Object target) {
		this.target = target;
	}
	

}

//配置文件

#xxx=java.util.ArrayList
xxx=com.enhance.proxy.aopfreamwork.ProxyFactoryBean
xxx.advice= com.enhance.proxy.MyAdvice
xxx.target=java.util.ArrayList
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值