Aspect Oriented Programming(AOP),面向切面編程,是一個比較熱門的話題。AOP主要實現的目的是針對業務處理過程中的切面進行提取,它所面對的是處理過程中的某個步驟或階段,以獲得邏輯過程中各部分之間低耦合性的隔離效果。比如我們最常見的就是日誌記錄了,舉個例子,我們現在提供一個查詢學生信息的服務,但是我們希望記錄有誰進行了這個查詢。如果按照傳統的OOP的實現的話,那我們實現了一個查詢學生信息的服務接口(StudentInfoService)和其實現 類 (StudentInfoServiceImpl.java),同時為了要進行記錄的話,那我們在實現類(StudentInfoServiceImpl.java)中要添加其實現記錄的過程。這樣的話,假如我們要實現的服務有多個呢?那就要在每個實現的類都添加這些記錄過程。這樣做的話就會有點繁瑣,而且每個實現類都與記錄服務日誌的行為緊耦合,違反了面向對象的規則。那么怎樣才能把記錄服務的行為與業務處理過程中分離出來呢?看起來好像就是查詢學生的服務自己在進行,但卻是背後日誌記錄對這些行為進行記錄,並且查詢學生的服務不知道存在這些記錄過程,這就是我們要討論AOP的目的所在。AOP的編程,好像就是把我們在某個方面的功能提出來與一批對象進行隔離,這樣與一批對象之間降低了耦合性,可以就某個功能進行編程。
基本介紹
- 中文名:面向切面編程
- 外文名:AOP(Aspect Oriented Programming)
- 語言:java
基本信息
代碼分析
接口實現方案
public interface StudentInfoService{void findInfo(String studentName);}
public class StudentInfoServiceImpl implements StudentInfoService{public void findInfo(String name){System.out.println("你目前輸入的名字是:"+name);}}
import org.apache.log4j.Logger;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;import java.lang.reflect.Method;public class MyHandler implements InvocationHandler{private Object proxyObj;private static Logger log=Logger.getLogger(MyHandler.class);public Object bind(Object obj){this.proxyObj=obj;return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);}public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{Object result=null;try{//請在這裡插入代碼,在方法前調用System.out.println("調用log日誌方法"+method.getName());result=method.invoke(proxyObj,args); //原方法//請在這裡插入代碼,方法後調用}catch(Exception e){e.printStackTrace();}return result;}}
public class AOPFactory{private static Object getClassInstance(String clzName){Object obj=null;try{Class cls=Class.forName(clzName);obj=(Object)cls.newInstance();}catch(ClassNotFoundException cnfe){System.out.println("ClassNotFoundException:"+cnfe.getMessage());}catch(Exception e){e.printStackTrace();}return obj;}public static Object getAOPProxyedObject(String clzName){Object proxy=null;MyHandler handler=new MyHandler();Object obj=getClassInstance(clzName);if(obj!=null) {proxy=handler.bind(obj);}else{System.out.println("Can't get the proxyobj");//throw}return proxy;}}
public class ClientTest{public static void main(String[] args){StudentInfoService studentInfo= (StudentInfoService)AOPFactory.getAOPProxyedObject("StudentInfoServiceImpl");studentInfo.findInfo("阿飛");}}
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
子類實現方案
public class StudentInfoServiceImpl{public void findInfo(String name){System.out.println("你目前輸入的名字是:"+name);}}
import net.sf.cglib.proxy.MethodInterceptor;import net.sf.cglib.proxy.Enhancer;import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;import org.apache.log4j.Logger;public class AOPInstrumenter implements MethodInterceptor{private Logger log=Logger.getLogger(AOPInstrumenter.class);private Enhancer enhancer=new Enhancer();public Object getInstrumentedClass(Class clz){enhancer.setSuperclass(clz);enhancer.setCallback(this);return enhancer.create();}public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy) throws Throwable{("調用日誌方法"+method.getName());Object result=proxy.invokeSuper(o,args);return result;}}
public class AOPTest{public static void main(String[] args){AOPInstrumenter instrumenter=new AOPInstrumenter();StudentInfoServiceImpl studentInfo=(StudentInfoServiceImpl)instrumenter.getInstrumentedClass(StudentInfoServiceImpl.class);studentInfo.findInfo("阿飛");}}