使用动态代理实现简单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)