理解完aop的名詞解釋,繼續學習spring aop的工作原理。
首先明確aop到底是什么東西?又如何不違單一原則並實現交叉處理呢?
如果對它的認識只停留在面向切面編程,那就臟了。從oop(Object Oriented Programming)說起,oop引入封裝,多態,繼承等概念建立對象層次的結構,處理公共行為屬性的集合。對於一個系統而言,需要把分散對象整合到一起的時候,oop就虛了,因為這樣的需求已經在對象層次之上了。如訂單模塊,還款模塊都需要User對象配合(當然不止於User對象完成的模塊),就需要UserService接口聲明的userServ對象配合來處理該模塊涉及User方面的工作,此時此刻就是面向UserServ接口編程。試想,如果沒有UserServ接口,那么系統各處涉及到User某一方面的工作就要相關的方法來處理,那么重復的代碼量可是太凶了~所以aop在系統中把某一類對象的功能抽象為一個接口。
參考這個逗比的栗子:http://blog.csdn.net/udbnny/article/details/5870076
那睡覺這件事來理解Spring aop,睡覺是我們關心的事,但是睡覺之前和起床之前都要做一些輔助的事情,如睡覺前脫衣,起床前穿衣。
首先需要一個睡覺的接口,這個接口誰都可以誰,人、機器、大象。。
public interface Sleepable { public void sleep(); }
然后Human來實現這個接口
public class Humman implements Sleepable { public void sleep() { System.out.println("夢中自有顏如玉!碎覺~ xxoxx"); } }
睡覺的輔助接口(脫衣服接口等。。)
public class SleepHelper implements MethodBeforeAdvice,AfterReturningAdvice{ public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("睡醒先穿衣服~"); } public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("睡覺先脫衣服~"); } }
簡單粗暴的組件都准備好了,怎么樣通過Spring配置文件將他們組合起來呢?在配置文件中繼續理解。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 俺們的bean --> <bean id="sleepHelper" class="test.spring.aop.bean.SleepHelper"></bean> <bean id="human" class="test.spring.aop.bean.Humman"></bean> <!-- 配置pointcut 切點相當於事故發生的地點 睡覺的這個動作在系統的什么地方出發的呢?--> <bean id="sleepPointcut" class="org.springframework.aop.support.JdkRegexpMethodPointcut"> <property name="pattern" value=".*sleep"></property> </bean> <!-- 通知 通知相當於事故時間及內容,連接切點和通知 sleepAdvisor這個色鬼准備把某個human睡覺這件事盡收眼底。。 --> <bean id="sleepHelperAdvisor" class="org.springframework.aop.support.DefaultPointcutAdvisor"> <property name="advice" ref="sleepHelper"></property> <property name="pointcut" ref="sleepPointcut"></property> </bean> <!-- 調用ProxyFactoryBean產生代理對象 現在我要搞清楚到底都發生了什么:human作為當事人,不好意思說話;sleepAdvisor是搞清睡覺這件事的關鍵,因為他看到了一切;包括睡覺以外的動作(proxyInterfaces) --> <bean id="humanProxy" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="human"></property> <property name="interceptorNames" value="sleepHelperAdvisor"></property> <property name="proxyInterfaces" value="test.spring.aop.bean.Sleepable"></property> </bean> </beans>
我已經搞清楚睡覺的來龍去脈了,還原下事情的經過。。
public class Test { public static void main(String[] args){ ApplicationContext appCtx = new ClassPathXmlApplicationContext("applicationContext.xml"); Sleepable sleeper = (Sleepable)appCtx.getBean("humanProxy"); sleeper.sleep(); } }
其實我已經知道結果了:
睡覺先脫衣服~
夢中自有顏如玉!碎覺~ xxoxx
睡醒先穿衣服~