目录
AOP介绍
AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。就是将交叉业务逻辑封装成切面,利用AOP的功能将切面织入到主业务逻辑中。所谓交叉业务逻辑是指,通用的、与主业务逻辑无关的代码若不使用AOP,则会出现代码纠缠,即交叉业务逻辑与主业务逻辑混合在一起。这样,会使主业务逻辑变的混杂不清。在代码执行过程中,动态嵌入其他代码,叫做面向切面编程。常见的使用场景:日志、事务、数据库操作等。
AOP中关键性概念
术语 | 说明 |
---|---|
连接点(Joinpoint) | 程序执行过程中明确的点,如方法的调用,或者异常的抛出. 注:完成具体的业务逻辑 |
目标(Target) | 被通知(被代理)的对象 注:完成切面编程 |
通知(Advice) | 在某种特定的连接点上所执行的动作 |
代理(Proxy) | 将通知应用到目标上所创建的对象(代理=通知+目标) 注:只有代理对象才有AOP功能,而AOP的代码是写在通知的方法里面的 |
切入点(Pointcut) | 多个连接点的集合,将通知应用到哪些连接点
|
适配器(Advisor) | 通知+切入点(相当于必须满足切入点的条件,才会应用通知部分)
|
AOP的实现方式
通知类型 | 说明 |
前置通知(MethodBeforeAdvice) | 目标方法执行之前调用 |
后置通知(AfterReturningAdvice) | 目标方法执行完成之后调用 |
环绕通知(MethodInterceptor) | 目标方法执行前后都会调用方法,且能增强结果 |
异常处理通知(ThrowsAdvice) | 目标方法出现异常调用 |
代理=通知+目标
- 创建目标接口和实现类
前置通知(MethodBeforeAdvice)
创建前置通知类
配置spring文件中前置配置
定义前置通知
<!--代理=通知+目标 只有完整的代理对象才具有AOP特性,而AOP代码是写在通知中-->
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--通知-->
<property name="interceptorNames">
<list>
<!--前置通知-->
<value>beforeAdvice</value>
<!--...此处加多个通知-->
</list>
</property>
<!--目标-->
<property name="target">
<ref bean="BookBizTarget"/>
</property>
<!--定义代理对象实现的接口-->
<property name="proxyInterfaces">
<list>
<value>biz.IBookBiz</value>
</list>
</property>
</bean>
初始化spring.xml上下文并执行目标方法
在这里的遵循了里氏替换原则
IBookBiz proxy=ac.getBean(s:"proxy",IBookBiz.class);
A
B C
B和C都实现了A,B和C有一个共同的父类A
A:IBookBiz
B:BookBizImpl
C:Proxy
代理(proxy)也实现了IBookBiz接口
BookBizImpl 实现了IBookBiz接口
所有用父类去接收,而不是用BookBizImpl
错误的方式接收
BookBizImpl proxy=ac.getBean(s:"proxy",BookBizImpl .class);
会出现
java.lang.ClassCastException: com.sun.proxy.$Proxy4 cannot be cast to 包路径.BookBizImpl
异常这里相当于
BookBizImpl proxy=(BookBizImpl )proxy
正确方式
IBookBiz bookBiz1=new BookBizImpl();
IBookBiz bookBiz2=new Proxy();
执行结果为
后置通知(AfterReturningAdvice)
创建后置通知类
配置spring文件中前置配置
定义后置通知
<!--代理=通知+目标 只有完整的代理对象才具有AOP特性,而AOP代码是写在通知中-->
<bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!--通知-->
<property name="interceptorNames">
<list>
<!--前置通知-->
<!--<value>beforeAdvice</value>-->
<!--后置通知-->
<value>afterAdvice</value>
<!--...此处加多个通知-->
</list>
</property>
<!--目标-->
<property name="target">
<ref bean="BookBizTarget"/>
</property>
<!--定义代理对象实现的接口-->
<property name="proxyInterfaces">
<list>
<value>biz.IBookBiz</value>
</list>
</property>
</bean>
初始化spring.xml上下文并执行目标方法
执行结果为
环绕通知(MethodInterceptor)
同上面步骤,只是实现MethodInterceptor接口
异常处理通知(ThrowsAdvice)
创建异常类
创建异常通知类
我在实现类中写入了一个判断书本价格书否为空和小于0
然后定义异常通知Bean
再在目标中使用异常通知Bean
价格为200d
价格为-200d
适配器(org.springframework.aop.support.RegexpMethodPointcutAdvisor)
适配器=通知+切入点
定义适配器Bena,在这里我用的通知是后置通知
这里的Value的值是方法名 .*方法名
后置通知的Bean
后置通知
再在代理中加入此适配器
执行结果为
代码提取码:rar8
至此,Spring之AOP介绍完毕,由于作者水平有限难免有疏漏,欢迎留言纠错。