Aspect Oriented Programming(AOP)錛岄潰鍚戝垏闈㈢紪紼嬶紝鏄竴涓瘮杈冪儹闂ㄧ殑璇濋銆侫OP涓昏瀹炵幇鐨勭洰鐨勬槸閽堝涓氬姟澶勭悊榪囩▼涓殑鍒囬潰榪涜鎻愬彇錛屽畠鎵闈㈠鐨勬槸澶勭悊榪囩▼涓殑鏌愪釜姝ラ鎴栭樁孌碉紝浠ヨ幏寰楅昏緫榪囩▼涓悇閮ㄥ垎涔嬮棿浣庤﹀悎鎬х殑闅旂鏁堟灉銆傛瘮濡傛垜浠渶甯歌鐨勫氨鏄棩蹇楄褰曚簡錛屼婦涓緥瀛愶紝鎴戜滑鐜板湪鎻愪緵涓涓湇鍔℃煡璇㈠鐢熶俊鎭殑錛屼絾鏄垜浠笇鏈涜褰曟湁璋佽繘琛屼簡榪欎釜鏌ヨ銆傚鏋滄寜鐓т紶緇熺殑OOP鐨勫疄鐜扮殑璇濓紝閭f垜浠疄鐜頒簡涓涓煡璇㈠鐢熶俊鎭殑鏈嶅姟鎺ュ彛(StudentInfoService)鍜屽叾瀹炵幇綾伙紙StudentInfoServiceImpl.java錛夛紝鍚屾椂涓轟簡瑕佽繘琛岃褰曠殑璇濓紝閭f垜浠湪瀹炵幇綾?StudentInfoServiceImpl.java)涓娣誨姞鍏跺疄鐜拌褰曠殑榪囩▼銆傝繖鏍風(fēng)殑璇濓紝鍋囧鎴戜滑瑕佸疄鐜扮殑鏈嶅姟鏈夊涓憿錛熼偅灝辮鍦ㄦ瘡涓疄鐜扮殑綾婚兘娣誨姞榪欎簺璁板綍榪囩▼銆傝繖鏍峰仛鐨勮瘽灝變細(xì)鏈夌偣綣佺悙錛岃屼笖姣忎釜瀹炵幇綾婚兘涓庤褰曟湇鍔℃棩蹇楃殑琛屼負(fù)绱ц﹀悎錛岃繚鍙嶄簡闈㈠悜瀵硅薄鐨勮鍒欍傞偅涔堟庢牱鎵嶈兘鎶婅褰曟湇鍔$殑琛屼負(fù)涓庝笟鍔″鐞嗚繃紼嬩腑鍒嗙鍑烘潵鍛紵鐪嬭搗鏉ュソ鍍忓氨鏄煡璇㈠鐢熺殑鏈嶅姟鑷繁鍦ㄨ繘琛岋紝浣嗘槸鑳屽悗鏃ュ織璁板綍瀵硅繖浜涜涓鴻繘琛岃褰曪紝浣嗘槸鏌ヨ瀛︾敓鐨勬湇鍔′笉鐭ラ亾瀛樺湪榪欎簺璁板綍榪囩▼錛岃繖灝辨槸鎴戜滑瑕佽璁篈OP鐨勭洰鐨勬墍鍦ㄣ侫OP鐨勭紪紼嬶紝濂藉儚灝辨槸鎶婃垜浠湪鏌愪釜鏂歸潰鐨勫姛鑳芥彁鍑烘潵涓庝竴鎵瑰璞¤繘琛岄殧紱伙紝榪欐牱涓庝竴鎵瑰璞′箣闂撮檷浣庝簡鑰﹀悎鎬э紝鍙互灝辨煇涓姛鑳借繘琛岀紪紼嬨?br> 鎴戜滑鐩存帴浠庝唬鐮佸叆鎵嬪惂錛岃瀹炵幇浠ヤ笂鐨勭洰鏍囷紝鎴戜滑鍙互浣跨敤涓涓姩鎬佷唬鐞嗙被(Proxy)錛岄氳繃鎷︽埅涓涓璞$殑琛屼負(fù)騫舵坊鍔犳垜浠渶瑕佺殑鍔熻兘鏉ュ畬鎴愩侸ava涓殑java.lang.reflect.Proxy綾誨拰java.lang.reflect.InvocationHandler鎺ュ彛涓烘垜浠疄鐜板姩鎬佷唬鐞嗙被鎻愪緵浜嗕竴涓柟妗堬紝浣嗘槸璇ユ柟妗堥拡瀵圭殑瀵硅薄瑕佸疄鐜版煇浜涙帴鍙o紱濡傛灉閽堝鐨勭洰鐨勬槸綾葷殑璇濓紝cglib涓烘垜浠彁渚涗簡鍙﹀涓涓疄鐜版柟妗堛傜瓑涓嬩細(xì)璇存槑涓よ呯殑鍖哄埆銆?br>涓銆佹帴鍙g殑瀹炵幇鏂規(guī)錛?br>1錛夐鍏堢紪鍐欐垜浠殑涓氬姟鎺ュ彛錛圫tudentInfoService.java錛夛細(xì)
public interface StudentInfoService{
void findInfo(String studentName);
}
鍙?qiáng)鍏跺疄鐜熬c伙紙StudentInfoServiceImpl.java錛夛細(xì)
public class StudentInfoServiceImpl implements StudentInfoService{
public void findInfo(String name){
System.out.println("浣犵洰鍓嶈緭鍏ョ殑鍚嶅瓧鏄?"+name);
}
}
2錛夌幇鍦ㄦ垜浠渶瑕佷竴涓棩蹇楀姛鑳斤紝鍦╢indInfo琛屼負(fù)涔嬪墠鎵ц騫惰褰曞叾琛屼負(fù)錛岄偅涔堟垜浠氨棣栧厛瑕佹嫤鎴琛屼負(fù)銆傚湪瀹為檯鎵ц鐨勮繃紼嬩腑鐢ㄤ竴涓唬鐞嗙被鏉ユ浛鎴戜滑瀹屾垚銆侸ava涓負(fù)鎴戜滑鎻愪緵浜嗗疄鐜板姩鎬佷唬鐞嗙被鐨勬柟妗堬細(xì)
1'澶勭悊鎷︽埅鐩殑鐨勭被錛圡yHandler.java錛?br>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{
//璇峰湪榪欓噷鎻掑叆浠g爜錛屽湪鏂規(guī)硶鍓嶈皟鐢?br> log.info("璋冪敤log鏃ュ織鏂規(guī)硶"+method.getName());
result=method.invoke(proxyObj,args); //鍘熸柟娉?br> //璇峰湪榪欓噷鎻掑叆浠g爜錛屾柟娉曞悗璋冪敤
}catch(Exception e){
e.printStackTrace();
}
return result;
}
}
2'鎴戜滑瀹炵幇涓涓伐鍘傦紝涓轟簡鏂逛究鎴戜滑浣跨敤璇ユ嫤鎴被(AOPFactory.java)錛?br>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;
}
}
3)鍩烘湰鐨勬嫤鎴笌鍏跺伐鍘傛垜浠兘瀹炵幇浜嗭紝鐜板湪嫻嬭瘯錛圕lientTest.java錛夛細(xì)
public class ClientTest{
public static void main(String[] args){
StudentInfoService studentInfo=(StudentInfoService)AOPFactory.getAOPProxyedObject("StudentInfoServiceImpl");
studentInfo.findInfo("闃塊");
}
}
杈撳嚭緇撴灉錛堢湅浣犵殑log4j璁劇疆錛夛細(xì)
[INFO]璋冪敤log鏃ュ織鏂規(guī)硶findInfo
浣犵洰鍓嶈緭鍏ョ殑鍚嶅瓧鏄?闃塊
榪欐牱鎴戜滑闇瑕佺殑鏁堟灉灝卞嚭鏉ヤ簡錛屼笟鍔″鐞嗚嚜宸卞湪榪涜錛屼絾鏄垜浠疄鐜頒簡鏃ュ織鍔熻兘錛岃屼笟鍔″鐞?StudentInfoService)鏍規(guī)湰涓嶇煡閬撳瓨鍦ㄨ琛屼負(fù)鐨勩備絾鏄疛ava涓彁渚涚殑鍔ㄦ佷唬鐞嗙被鐨勫疄鐜版槸閽堝瀹炵幇浜嗘煇浜涙帴鍙g殑綾伙紝濡傛灉娌℃湁瀹炵幇鎺ュ彛鐨勮瘽錛屼笉鑳藉垱寤轟唬鐞嗙被錛岀湅浠ヤ笂閮ㄥ垎錛?br>return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),this);
鐪嬪埌浜嗘病鏈夛紵obj.getClass().getInterfaces()瑕佹眰瀹炵幇浜嗘煇浜涙帴鍙c備互涓嬫彁渚涘摢浜涙病鏈夊疄鐜版帴鍙g殑瀹炵幇鏂規(guī)錛?br>
浜屻佸瓙綾葷殑瀹炵幇鏂規(guī)銆?br> 棣栧厛錛岃涓婄綉涓婥GLib鐨勫寘錛?a >http://sourceforge.net/project/showfiles.php?group_id=56933 銆傝緗ソclasspath璺緞錛孋GLib涓巎ava鏍囧噯搴撴彁渚涚殑瀹炵幇鏂規(guī)涓嶅悓錛宑glib涓昏鏄熀浜庡疄鐜扮被錛堝StudentInfoServiceImpl.java)鎵╁睍涓涓瓙綾繪潵瀹炵幇銆備笌Dynamic Proxy涓殑Proxy鍜孖nvocationHandler鐩稿搴旓紝net.sf.cglib.proxy.Enhancer鍜孧ethodInterceptor鍦–GLib涓礋璐e畬鎴愪唬鐞嗗璞″垱寤哄拰鏂規(guī)硶鎴幏澶勭悊,浜х敓鐨勬槸鐩爣綾葷殑瀛愮被鑰屼笉鏄氳繃鎺ュ彛鏉ュ疄鐜版柟娉曟嫤鎴殑錛孍nhancer涓昏鏄敤浜庢瀯閫犲姩鎬佷唬鐞嗗瓙綾繪潵瀹炵幇鎷︽埅錛孧ethodInterceptor錛堟墿灞曚簡Callback鎺ュ彛錛変富瑕佺敤浜庡疄鐜癮round advice錛圓OP涓殑姒傚康錛夛細(xì)
1錛夋垜浠殑涓氬姟澶勭悊錛圫tudentInfoServiceImpl.java錛夛細(xì)
public class StudentInfoServiceImpl{
public void findInfo(String name){
System.out.println("浣犵洰鍓嶈緭鍏ョ殑鍚嶅瓧鏄?"+name);
}
}
2錛夊疄琛屼竴涓伐鍏鋒潵澶勭悊鏃ュ織鍔熻兘錛圓OPInstrumenter.java錛夛細(xì)
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{
log.info("璋冪敤鏃ュ織鏂規(guī)硶"+method.getName());
Object result=proxy.invokeSuper(o,args);
return result;
}
}
3錛夋垜浠潵嫻嬭瘯涓涓嬶紙AOPTest.java錛夛細(xì)
public class AOPTest{
public static void main(String[] args){
AOPInstrumenter instrumenter=new AOPInstrumenter();
StudentInfoServiceImpl studentInfo=(StudentInfoServiceImpl)instrumenter.getInstrumentedClass(StudentInfoServiceImpl.class);
studentInfo.findInfo("闃塊");
}
}
杈撳嚭緇撴灉涓庝互涓婄浉鍚屻?br> CGLib涓負(fù)瀹炵幇浠ヤ笂鐩殑錛屼富瑕佹彁渚涚殑綾?br>1)Enhancer錛歴etCallback(Callback) ,setSuperclass(Class) ,create()榪斿洖鍔ㄦ佸瓙綾籓bject
2)MethodInterceptor蹇呴』瀹炵幇鐨勬帴鍙o細(xì)intercept(Object,Method,Object[],MethodProxy)榪斿洖鐨勬槸鍘熸柟娉曡皟鐢ㄧ殑緇撴灉銆傚拰Proxy鍘熺悊涓鏍楓?
涓夈佷互涓婄殑涓や釜綆鍗曞疄鐜癆OP鐨勬柟妗堥兘涓轟綘鍑嗗濂戒簡錛屼綘鍙互鑷繁緙栧啓嫻嬭瘯涓涓嬶紝浠ヤ笅綆鍗曚粙緇嶄竴涓婣OP鐨勫熀鏈蹇碉細(xì)
1錛塧spect錛堝垏闈級錛氬疄鐜頒簡cross-cutting鍔熻兘錛屾槸閽堝鍒囬潰鐨勬ā鍧椼傛渶甯歌鐨勬槸logging妯″潡錛岃繖鏍鳳紝紼嬪簭鎸夊姛鑳借鍒嗕負(fù)濂藉嚑灞傦紝濡傛灉鎸変紶緇熺殑緇ф壙鐨勮瘽錛屽晢涓氭ā鍨嬬戶鎵挎棩蹇楁ā鍧楃殑璇濇牴鏈病鏈変粈涔堟剰涔夛紝鑰岄氳繃鍒涘緩涓涓猯ogging鍒囬潰灝卞彲浠ヤ嬌鐢ˋOP鏉ュ疄鐜扮浉鍚岀殑鍔熻兘浜嗐?br>2錛塲ointpoint錛堣繛鎺ョ偣錛夛細(xì)榪炴帴鐐規(guī)槸鍒囬潰鎻掑叆搴旂敤紼嬪簭鐨勫湴鏂癸紝璇ョ偣鑳借鏂規(guī)硶璋冪敤錛岃屼笖涔熶細(xì)琚姏鍑烘剰澶栥傝繛鎺ョ偣鏄簲鐢ㄧ▼搴忔彁渚涚粰鍒囬潰鎻掑叆鐨勫湴鏂癸紝鍙互娣誨姞鏂扮殑鏂規(guī)硶銆傛瘮濡備互涓婃垜浠殑鍒囩偣鍙互璁や負(fù)鏄痜indInfo(String)鏂規(guī)硶銆?br>3錛塧dvice錛堝鐞嗛昏緫錛夛細(xì)advice鏄垜浠垏闈㈠姛鑳界殑瀹炵幇錛屽畠閫氱煡紼嬪簭鏂扮殑琛屼負(fù)銆傚鍦╨ogging閲岋紝logging advice鍖呮嫭logging鐨勫疄鐜頒唬鐮侊紝姣斿鍍忓啓鏃ュ織鍒頒竴涓枃浠朵腑銆俛dvice鍦╦ointpoint澶勬彃鍏ュ埌搴旂敤紼嬪簭涓備互涓婃垜浠湪MyHandler.java涓疄鐜頒簡advice鐨勫姛鑳?br>4錛塸ointcut錛堝垏鐐癸級錛歱ointcut鍙互鎺у埗浣犳妸鍝簺advice搴旂敤浜巎ointpoint涓婂幓錛岄氬父浣犱嬌鐢╬ointcuts閫氳繃姝e垯琛ㄨ揪寮忔潵鎶婃槑鏄劇殑鍚嶅瓧鍜屾ā寮忚繘琛屽尮閰嶅簲鐢ㄣ傚喅瀹氫簡閭d釜jointpoint浼?xì)鑾峰緱閫氱煡銆?br>5錛塱ntroduction錛氬厑璁告坊鍔犳柊鐨勬柟娉曞拰灞炴у埌綾諱腑銆?br>6錛塼arget錛堢洰鏍囩被錛夛細(xì)鏄寚閭d簺灝嗕嬌鐢╝dvice鐨勭被錛屼竴鑸槸鎸囩嫭绔嬬殑閭d簺鍟嗗姟妯″瀷銆傛瘮濡備互涓婄殑StudentInfoServiceImpl.
7)proxy錛堜唬鐞嗙被錛夛細(xì)浣跨敤浜唒roxy鐨勬ā寮忋傛槸鎸囧簲鐢ㄤ簡advice鐨勫璞★紝鐪嬭搗鏉ュ拰target瀵硅薄寰堢浉浼箋?br>8錛墂eaving(鎻掑叆錛夛細(xì)鏄寚搴旂敤aspects鍒頒竴涓猼arget瀵硅薄鍒涘緩proxy瀵硅薄鐨勮繃紼嬶細(xì)complie time錛宑lassload time錛宺untime