Spring默认使用JDK动态代理来实现AOP,如果业务对象没有实现接口,默认使用CGLIB代理,面向接口编程是一个良好得习惯,尽量不要面向具体类
首先,有个Dog接口
package
AOP.SimapleAOP;
public interface Dog ... {
public void info();
public void run();
}
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("我奔跑迅速");
}
}
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;
}
}
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;
}
}
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);
}
}
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();
}
}
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
我奔跑迅速