---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
为已经写好的类增加功能
客户端程序不在直接调用目标类,而是调用代理类,代理类在代码里面调用目标类,在加上额外的增强功能,代理类和目标类要实现相同的接口
1、 AOP切面编程
系统中存在交叉业务,一个交叉业务就是要切入到系统中的一个方面,交叉业务的编程问题即为面向方面的编程,AOP的目标就是要使交叉业务模块化
2、 动态代理
JVM生成的动态类必须实现一个或多个接口
让JVM创建动态类需要提供的信息:生成的类中有哪些方法,通过让其实现那些接口的方式进行告知、产生的类字节码必须有一个关联的类加载器对象、生成的类中的方法的代码是怎样的,也得有我们提供,把我们的代码写在一个约定好的接口对象方法中,把对象传给它,它调用我的方法,即相当于插入了我的代码。提供执行代码的对象就是那个InvocationHandler对象,它是在创建动态类的实例对象的构造方法时传递进去的。
注:只有tostring,hashCold,equlse这三个方法委托为handler其它的不委托/**
*获得一个动态类 并实例化对象
* @author Administrator
*
*/
public class ProctCollection {
public static void main(String[] args) throws Exception{
//得到构造函数
//第一个参数表示用什么类加载器,第二而参数是实现接口
Class Clazzproxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
Constructor[] constructors = Clazzproxy1.getConstructors();
for (Constructor constructor : constructors) {
//单线程的时候用StringBuilder多线程的时候用StringBuffer
//StringBuffer考虑线程安全问题,效率不高,Stringbuilder不考虑线程安全
StringBuilder builder = new StringBuilder();
String name = constructor.getName();
builder.append(name);
builder.append('(');
Type[] types = constructor.getGenericParameterTypes();
for (Type type : types) {
builder.append(type);
builder.append(',');
}
if (types!=null&&types.length!=0) {
builder.deleteCharAt(builder.lastIndexOf(","));
}
builder.append(')');
System.out.println(builder.toString());
}
//对象发发
Method[] methods = Clazzproxy1.getMethods();
for (Method method : methods) {
//单线程的时候用StringBuilder多线程的时候用StringBuffer
//StringBuffer考虑线程安全问题,效率不高,Stringbuilder不考虑线程安全
StringBuilder builder = new StringBuilder();
String name = method.getName();
builder.append(name);
builder.append('(');
Type[] types = method.getGenericParameterTypes();
for (Type type : types) {
builder.append(type);
builder.append(',');
}
if (types!=null&&types.length!=0) {
builder.deleteCharAt(builder.lastIndexOf(","));
}
builder.append(')');
System.out.println(builder.toString());
}
//实例化对象
class MyInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
}
Collection proxy1 = (Collection) Clazzproxy1.getConstructor(InvocationHandler.class).newInstance(new MyInvocationHandler());
Collection proxy2 = (Collection) Clazzproxy1.getConstructor(InvocationHandler.class).newInstance(new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
Collection proxy3 = (Collection) Proxy.newProxyInstance(
Collection.class.getClassLoader(),
new Class[]{Collection.class},
new InvocationHandler() {
//三个参数分别表示,调用的是哪个代理,代理的方法,方法的参数 proxy3.add("asd");
ArrayList aList = new ArrayList();
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//代理增加功能
long starTime = System.currentTimeMillis();
//目标返回结果
Object relVal = method.invoke(aList, args);
//代理增加功能
long endTime = System.currentTimeMillis();
System.out.println(endTime-starTime);
return relVal;
}
});
proxy3.add("asd");
proxy3.add("qwe");
proxy3.add("zxc");
System.out.println(proxy3.size());
}
}
---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------