------Java培训、Android培训、iOS培训、.Net培训、期待与您交流! -------
AOP:面向方面的编程——目标是要将交叉业务模块化
安全、事务、日志等功能要贯穿到好多个模块中,这就是交叉业务
动态代理技术
JVM可以在运行期动态生成出类的字节码,这种动态生成的类往往被用作代理类,即动态代理类。
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;
public class ProxyTest {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
Class clazzProxy1 = Proxy.getProxyClass(Collection.class.getClassLoader(), Collection.class);
System.out.println(clazzProxy1.getName());
Constructor[] constructors = clazzProxy1.getConstructors();
for(Constructor constructor : constructors){
String name = constructor.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = constructor.getParameterTypes();
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
Method[] methods = clazzProxy1.getMethods();
for(Method method : methods){
String name = method.getName();
StringBuilder sBuilder = new StringBuilder(name);
sBuilder.append('(');
Class[] clazzParams = method.getParameterTypes();
for(Class clazzParam : clazzParams){
sBuilder.append(clazzParam.getName()).append(',');
}
if(clazzParams!=null && clazzParams.length != 0)
sBuilder.deleteCharAt(sBuilder.length()-1);
sBuilder.append(')');
System.out.println(sBuilder.toString());
}
Constructor constructor = clazzProxy1.getConstructor(InvocationHandler.class);
class MyInvocationHander1 implements InvocationHandler{
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
Collection proxy1 = (Collection)constructor.newInstance(new MyInvocationHander1());
System.out.println(proxy1);
proxy1.clear();
Collection proxy2 = (Collection)constructor.newInstance(new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
return null;
}
});
final ArrayList target = new ArrayList();
Collection proxy3 = (Collection)getProxy(target,new MyAdvice());
proxy3.add("zxx");
proxy3.add("lhm");
proxy3.add("bxd");
System.out.println(proxy3.size());
System.out.println(proxy3.getClass().getName());
}
private static Object getProxy(final Object target,final Advice advice) {
Object proxy3 = Proxy.newProxyInstance(
target.getClass().getClassLoader(),
new InvocationHandler(){
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
/*long beginTime = System.currentTimeMillis();
Object retVal = method.invoke(target, args);
long endTime = System.currentTimeMillis();
System.out.println(method.getName() + " running time of " + (endTime - beginTime));
return retVal;*/
advice.beforeMethod(method);
Object retVal = method.invoke(target, args);
advice.afterMethod(method);
return retVal;
}
}
);
return proxy3;
}
}
1、在调用目标方法之前
2、在调用目标方法之后
3、在调用目标方法前后
4、在处理目标方法异常的catch块中
动态代理的三种创建方式
1、Proxy.getProxyClass(类加载,接口)获取字节码文件,再根据字节码获取构造函数,Proxy只有一个带参的构造函数参数位。InvocationHandler的对象,通过反射获取,在new InvocationHandler获取对象
2、使用匿名内部类:new InvocationHandler(){}
3、Proxy.newProxyInstance方法