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、付费专栏及课程。

余额充值