理解完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
睡醒先穿衣服~