动态代理与AOP Aspect Orient Programming
1.没有使用动态代理切面
前面介绍的Proxy和InvocationHandler,很难看出这种动态代理的优势,下面介绍一种更实用的动态代理机制
改进后的说明:代码段1、代码段2、代码段3和深色代码段分离开了,但代码段1、2、3又和一个特定的方法A耦合了!最理想的效果是:代码块1、2、3既可以执行方法A,又无须在程序中以硬编码的方式直接调用深色代码的方法
2. 例子
/**
*
*/
package testAOP;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface Human{
void info();
void fly();
}
//被代理类
class SuperMan implements Human{
@Override
public void info() {
System.out.println("I am SuperMan");
}
@Override
public void fly() {
System.out.println("I believe I can Fly");
}
}
class HumanUtil{
public void method1() {
System.out.println("====方法一====");
}
/*
* 执行代码method1和method2动态的插入一段代码
*/
public void method2() {
System.out.println("====方法二====");
}
}
class MyInvocationHandler implements InvocationHandler{
Object obj;//被代理类的声明
public void setObject(Object obj) {
this.obj = obj;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
HumanUtil h = new HumanUtil();
h.method1();//固定的代码
Object returnval = method.invoke(obj, args);//动态代码
h.method2();//固定的代码
return returnval;
}
}
//动态的创建一个代理类的对象
class MyProxy{
//动态的创建一个代理类的对象
public static Object getProxyInstance(Object obj){
MyInvocationHandler handler = new MyInvocationHandler();
handler.setObject(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);
}
}
public class TestAOP {
public static void main(String[] args) {
//创建一个被代理的对象
SuperMan man = new SuperMan();
Object obj = MyProxy.getProxyInstance(man);//返回一个代理类对象
Human hu = (Human)obj;
hu.info();//通过代理类的对象调用重写的抽象方法
System.out.println();
hu.fly();
}
}
3. 概述
- 使用Proxy生成一个动态代理时,往往并不会凭空产生一个动态代理,这样没有太大的意义。通常都是为指定的目标对象生成动态代理
- 这种动态代理在AOP中被称为AOP代理,AOP代理可代替目标对象,AOP代理包含了目标对象的全部方法。但AOP代理中的方法与目标对象的方法存在差异:AOP代理里的方法可以在执行目标方法之前、之后插入一些通用处理