使用动态代理实现简单AOP

Spring默认使用JDK动态代理来实现AOP,如果业务对象没有实现接口,默认使用CGLIB代理,面向接口编程是一个良好得习惯,尽量不要面向具体类

首先,有个Dog接口

package AOP.SimapleAOP;

public interface Dog ...{
   public void info();
   public void run();
}

 然后给出这个接口的实现类:

package AOP.SimapleAOP;


public class DogImpl implements Dog ...{

    public void info() ...{
        System.out.println("我是一只猎狗");
    }

    public void run() ...{
        System.out.println("我奔跑迅速");
    }

    

}

 

DogFactory:

package AOP.SimapleAOP;

public class DogFactory ...{
   private static DogFactory df;
   private Dog gundog;
   private DogFactory()...{
       
   }
   public static DogFactory instantce()...{
       if(df==null)...{
           df=new DogFactory();
       }
       return df;
   }
   public Dog getDog(String dogName)...{
       if(dogName.equals("gundog"))...{
           if(gundog==null)...{
               return new DogImpl();
           }
           return gundog;
       }
       return null;
   }
}

 

 

 下面是一个通用类:没有和任何特定的类耦合

 

package AOP.SimapleAOP;

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

public class ProxyHandler implements InvocationHandler ...{
    private Object targetObject;
    public void setTargetObject(Object targetObject) ...{
        this.targetObject = targetObject;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable ...{
        Object result=null;
        if(method.getName().equals("info"))...{
            System.out.println("begin");
            result=method.invoke(targetObject, args);
            System.out.println("end");
        }
        else...{
            result=method.invoke(targetObject, args);
        }
        return null;
    }
    
} 

 

上述代码通过mehtod对象的invoke方法,可以完成目标对象得方法可调用,目标是Object类型,可以使任何业务实现类,在目标对象的info方法中,进行了功能增强(多打印了begin和end)

代理工厂:

package AOP.SimapleAOP;

import java.lang.reflect.Proxy;

public class MyProxyFacytory ...{
   public static Object getProxy(Object object)...{
       ProxyHandler handler=new ProxyHandler();
       handler.setTargetObject(object);
       //第一参数用来创建动态代理的ClassLoader对象,只能该对象能访问dog接口即可
       //第二个参数是接口数组
       //第三个参数是代理包含的处理实例
       return Proxy.newProxyInstance(DogImpl.class.getClassLoader(), object.getClass().getInterfaces(), handler);
   }
} 

 

Dynamic Proxy要求被代理的必须是接口的实现类,都则无法为其构造相应的动态类,所以Spring对接口全部采用Dynamic Proxy 实现AOP,对没有实现接口的类采用CGLIB

测试代码:

package AOP.SimapleAOP;

public class Test ...{

    public static void main(String[] args) ...{
        Dog dog=null;
        Dog targetObject=DogFactory.instantce().getDog("gundog");
        Object proxy=MyProxyFacytory.getProxy(targetObject);
        if(proxy instanceof Dog)...{
            dog=(Dog)proxy;
        }
        dog.info();
        dog.run();
    }

}

 

结果:

begin
我是一只猎狗
end
我奔跑迅速

你可能感兴趣的:(Spring)