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
我奔跑迅速