aop的概述

支付部分,定义IPayService接口并定义支付方法“pay”,并定义了两个实现:“PointPayService”表示积分支付,“RMBPayService”表示人民币支付;并且在每个支付实现中支付逻辑和记录日志

记录日志时,如果使用oop,则每个接口的实现类里重复编写日志的代码,aop就是为了解耦,将日志的功能变成切面,在合适的时候织入到里面

在进行OOP开发时,都是基于对组件(比如类)进行开发,然后对组件进行组合,OOP最大问题就是无法解耦组件进行开发,比如我们上边举例,而AOP就是为了克服这个问题而出现的,它来进行这种耦合的分离。

AOP为开发者提供一种进行横切关注点(比如日志关注点横切了支付关注点)分离并织入的机制,把横切关注点分离,然后通过某种技术织入到系统中,从而无耦合的完成了我们的功能。

AOP主要用于横切关注点分离和织入,因此需要理解横切关注点和织入:

  • 关注点:可以认为是所关注的任何东西,比如上边的支付组件;
  • 关注点分离:将问题细化从而单独部分,即可以理解为不可再分割的组件,如上边的日志组件和支付组件;
  • 横切关注点:一个组件无法完成需要的功能,需要其他组件协作完成,如日志组件横切于支付组件;
  • 织入:横切关注点分离后,需要通过某种技术将横切关注点融合到系统中从而完成需要的功能,因此需要织入,织入可能在编译期、加载期、运行期等进行。

横切关注点可能包含很多,比如非业务的:日志、事务处理、缓存、性能统计、权限控制等等这些非业务的基础功能;还可能是业务的:如某个业务组件横切于多个模块。

简单入门案例

1)定义目标接口:

java代码:

  1. package cn.javass.spring.chapter6.service;
  2. public interface IHelloWorldService {
  3. public void sayHello();
  4. }

2)定义目标接口实现:

java代码:

  1. package cn.javass.spring.chapter6.service.impl;
  2. import cn.javass.spring.chapter6.service.IHelloWorldService;
  3. public class HelloWorldService implements IHelloWorldService {
  4. @Override
  5. public void sayHello() {
  6. System.out.println("============Hello World!");
  7. }
  8. }

注:在日常开发中最后将业务逻辑定义在一个专门的service包下,而实现定义在service包下的impl包中,服务接口以IXXXService形式,而服务实现就是XXXService,这就是规约设计,见名知义。当然可以使用公司内部更好的形式,只要大家都好理解就可以了。

定义切面支持类

有了目标类,该定义切面了,切面就是通知和切入点的组合,而切面是通过配置方式定义的,因此这定义切面前,我们需要定义切面支持类,切面支持类提供了通知实现:

java代码:

  1. package cn.javass.spring.chapter6.aop;
  2. public class HelloWorldAspect {
  3. //前置通知
  4. public void beforeAdvice() {
  5. System.out.println("===========before advice");
  6. }
  7. //后置最终通知
  8. public void afterFinallyAdvice() {
  9. System.out.println("===========after finally advice");
  10. }
  11. }

此处HelloWorldAspect类不是真正的切面实现,只是定义了通知实现的类,在此我们可以把它看作就是缺少了切入点的切面。

注:对于AOP相关类最后专门放到一个包下,如“aop”包,因为AOP是动态织入的,所以如果某个目标类被AOP拦截了并应用了通知,可能很难发现这个通知实现在哪个包里,因此推荐使用规约命名,方便以后维护人员查找相应的AOP实现。

有了通知实现,那就来配置切面

java代码:

  1. <bean id="helloWorldService"
  2. class="cn.javass.spring.chapter6.service.impl.HelloWorldService"/>

java代码:

  1. <bean id="aspect" class="cn.javass.spring.chapter6.aop.HelloWorldAspect"/>
  2. <aop:config>
  3. <aop:pointcut id="pointcut" expression="execution(* cn.javass..*.*(..))"/>
  4. <aop:aspect ref="aspect">
  5. <aop:before pointcut-ref="pointcut" method="beforeAdvice"/>
  6. <aop:after pointcut="execution(* cn.javass..*.*(..))" method="afterFinallyAdvice"/>
  7. </aop:aspect>
  8. </aop:config>

切入点使用<aop:config>标签下的<aop:pointcut>配置,expression属性用于定义切入点模式,默认是AspectJ语法,“execution(* cn.javass..*.*(..))”表示匹配cn.javass包及子包下的任何方法执行。

切面使用<aop:config>标签下的<aop:aspect>标签配置,其中“ref”用来引用切面支持类的方法。

前置通知使用<aop:aspect>标签下的<aop:before>标签来定义,pointcut-ref属性用于引用切入点Bean,而method用来引用切面通知实现类中的方法,该方法就是通知实现,即在目标类方法执行之前调用的方法。

最终通知使用<aop:aspect>标签下的<aop:after >标签来定义,切入点除了使用pointcut-ref属性来引用已经存在的切入点,也可以使用pointcut属性来定义,如pointcut="execution(* cn.javass..*.*(..))",method属性同样是指定通知实现,即在目标类方法执行之后调用的方法。

运行测试

测试类非常简单,调用被代理Bean跟调用普通Bean完全一样,Spring AOP将为目标对象创建AOP代理,具体测试代码如下:

java代码:

  1. package cn.javass.spring.chapter6;
  2. import org.junit.Test;
  3. import org.springframework.context.ApplicationContext;
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;
  5. import cn.javass.spring.chapter6.service.IHelloWorldService;
  6. import cn.javass.spring.chapter6.service.IPayService;
  7. public class AopTest {
  8. @Test
  9. public void testHelloworld() {
  10. ApplicationContext ctx =  new ClassPathXmlApplicationContext("chapter6/helloworld.xml");
  11. IHelloWorldService helloworldService =
  12. ctx.getBean("helloWorldService", IHelloWorldService.class);
  13. helloworldService.sayHello();
  14. }
  15. }

该测试将输出如下如下内容:

java代码:

  1. ===========before advice
  2. ============Hello World!
  3. ===========after finally advice

时间: 2024-10-18 20:14:55

aop的概述的相关文章

[Spring实战系列](16)面向切面编程(AOP)概述

1. 简介 在软件中,有些行为对于大多数应用都是通用的.日志,安全和事务管理的确很重要,但他们是都是应用对象主动参与的行为呢?如果让应用对象只关注自己所针对的业务领域问题,而其他方面的问题由其他应用对象来处理,这样会不会更好? 在软件开发中,分布于应用中多处的功能被称为横切关注点.通常,这些横切关注点从概念上是与应用的业务逻辑相分离的(但是往往直接嵌入到应用的业务逻辑中).将这些横切关注点与业务逻辑相分离是面向切面编程索要解决的. 上图展示了一个被划分为模块的典型应用.每个模块的核心功能都是为特

AOP的概述(7)

什么是AOP? AOP Aspect Oriented Programing 面向切面编程 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) Spring AOP使用纯Java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码 AspecJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的

九 AOP的概述

AOP : 面向切面编程,解决OOP(面向对象编程)开发遇到的问题,是oop的延伸和扩展 AOP的优点:不修改源码的情况下,对程序进行校验,日志记录,性能控制,事务控 SpringAOP底层的实现原理: JDK动态代理:只能对实现了接口的类产生代理.(实现接口默认JDK动态代理,底层自动切换) cglib动态代理(类似Javassist第三方的代理技术):对没有实现接口的类产生代理对象.生成子类对象. AOP采用了横向抽取机制取代了传统的纵向继承 原文地址:https://www.cnblogs

Spring AOP源码分析

AOP基本概述 Advice(通知) BeforeAdvice package org.springframework.aop; import java.lang.reflect.Method; public interface MethodBeforeAdvice extends BeforeAdvice { void before(Method method, Object[] args, Object target) throws Throwable; } before是回调方法,在Adv

AOP技术分析

AOP的概述(http://www.cnblogs.com/lxp503238/p/6837653.html)        1. 什么是AOP的技术?        * 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程        * AOP是一种编程范式,隶属于软工范畴,指导开发者如何组织程序结构        * AOP最早由AOP联盟的组织提出的,制定了一套规范.Spring将AOP思想引入到框架中,必须遵守AOP联盟的规范      

轻量级的.NET对象查找服务和AOP开发框架Netop.Core源码解说(1)-导言

Netop.Core是我程序开发积累的一个轻量级的.NET对象查找服务和AOP开发框架,现将源码公开,共享给各位NET程序员后面相关的文章对这个开发框架进行程序解说和使用解说. Netop.Core--轻量级的.NET对象查找服务和AOP开发框架概述:1.    对象查找服务(本地服务实例生成,远程服务,WCF服务)和AOP服务.2.    其它普通服务:配置, 对话上下文,日志,缓冲等.3.    类库:Netop.Core.dll  4.    必需的外部类库:Microsoft.Pract

Spring框架 AOP(三)

AOP理论概述 Aspect Oriented Programming 面向切面编程 业界 AOP 实际上 OOP (面向对象编程 ) 延伸 -- OOP编程语言. AOP设计思想 AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查.缓存) 横向抽取代码复用,基于代理技术,在不修改原有对象代码情况下,对原有对象方法功能进行增强! ---- AOP 思想 Spring框架如何实现AOP Spring1.2 版本开始 开始支持AOP技术 (传统Spring AOP

Spring框架 教程

Spring教程 Spring教程...1 Spring框架概述...3 Spring是什么?...3 Spring的历史...4 Spring的使命(MissionStatement)...4 Spring受到的批判...4 Spring包含的模块...5 总结...6 Spring的IoC容器...6 用户注册的例子...7 面向接口编程...8 (用户持久化类)重构第一步--面向接口编程... 重构第二步--工厂(Factory)模式... 重构第三步--工厂(Factory)模式的改进.

Spring框架第二天

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption