Aop是干嘛的为什么要使用它

在业务系统中,总有一些散落,渗透到系统的各处且不得不处理的事情,这些穿插在既定业务中的操作就是所谓的“横切逻辑”,也称切面,

我们怎样才不受这些附加要求的干扰,专心于真正的业务逻辑呢?我们很容易想到可以将这些重复性的代码抽取出来,放在专门的类和方

法中,这样便于管理和维护了。但即便如此,依然无法实现既定业务和横切逻辑的彻底解耦合因为业务代码中还要波阿里这些方法的调用

代码,当需要增加或减少横切逻辑的时候,还是要修改业务逻辑的时候,还是要修改业务方法中的调用代码才能实现。我们希望无须编写

显示的调用,在需要的时候,系统能够“自动”调用所需的功能,这正是AOP要解决的问题。

什么是面向切面编程

  简答的说就是在不改变原程序的基础上为代码段增加新的功能,对代码段进行增强处理。它的设计思想来源于代理设计模式。在这种模

式下给编程人员的感觉是在原有代码乃至原业务不修改的勤快下,直接在业务流程中切入新代码,增加新功能,这就是所谓的面向切面编程

对概念有了一些了解后,还需了解一些基本概念。

  • 切面(Aspect):一个模块化的横切逻辑(或称横切关注点),可能会横切多个对象。一个饭店可以提供给多人一起吃饭类似于这种概念
  • 连接点(Join Poin):接点是个虚的概念,可简单理解为切入点的集合;它只是对应用程序的所有需要进行插入切面的一个统称。
  • 增强处理(Adive):切面在某个特定连接点上执行的代码逻辑。如到饭店吃完饭不用自洗碗,做饭。
  • 切入点(pointcut):对连接点的特征进行描述,可以使用正则表达式。增强处理和一个切入点表达式相关联,并在与这个切入点匹配的某个连接点上运行。
  • 目标对象(Target object):被一个或多个切面增强的对象。
  • AOP代理(AOP proxy):由AOP框架所创建的对象,实现执行增强处理的方法等功能。
  • 织入(Weaving):将增强处理连接到应用程序中的类型或对象的过程。
  • 增强处理类型:前置增强,后置增强,环绕增强,异常抛出增强,最终增强。
增强处理类型的先后执行顺序:前置 环绕 环绕 最终 异常|后置。异常抛出增强则是方法中出了异常才会执行,执行了异常,后置则不会执行

好,概念的东西也就差不多这些了,来看下列子

定义一个people类

public class People {
/**
* 客户名
*/
private String name;
/**
*吃饭的方法
*/
public void havingDinner() {
System.out.println(name+"吃饭中...吃完了");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

定义一个饭店

/**
*定义切面
*/
public class Hotel {
public void order() {
System.out.println("点菜完毕上菜");
}
public void Dishwashing() {
System.out.println("客人吃完,洗碗");
}
}

上面的两个代码为增强处理

aop相关代码如下

<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd ">
  <bean id="people" class="cn.People" p:name="小明"/>
<!-- 创建hotel对象-->
<bean id="hotel" class="cn.Hotel"/>
<!-- aop代理 -->
<aop:config>
<!-- 切入点,expression为条件 只有符合要求的才可以进入饭店吃饭 id为条件名-->
<aop:pointcut expression="execution(public void havingDinner())" id="pointcut"/>
<!-- ref属性通过htoel引用定义的切面 -->
<aop:aspect ref="htole">
<!-- 吃饭之前进行此功能调用 并且满足匹配条件才调用饭店里点菜和上菜的方法 此标签为前置增强-->
<aop:before method="order" pointcut-ref="pointcut"/>
<!-- 吃饭之后才进行功能调用 并满足匹配条件饭店里洗碗的方法 此标签为后置增强 -->
<aop:after-returning method="Dishwashing" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
aop:befoer为前置增强的标签
aop:after-returning为后置增强标签 其中methid属性为饭店里的方法名称。即增强处理的名称 测试类代码如下
  public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("peopleConfig.xml");
People people = (People)context.getBean("people");
people.havingDinner();
}
结果为
其中增强处理就是执行的点菜上菜及洗碗的方法,目标对象即使当中符合匹配条件的方法即为目标对象。
织入指的是行为把增强处理连接到目标对象即为织入,即把点菜和洗碗与吃饭连接起来这一过程为织入。
其它增强类型如下
<bean id="people" class="cn.People" p:name="小明"/>
<bean id="hotel" class="cn.Hotel"/>
<!-- aop代理 -->
<aop:config>
<aop:pointcut expression="execution(public String havingDinner())" id="pointcut"/>
<aop:aspect ref="hotel">
<aop:before method="order" pointcut-ref="pointcut"/>
<!-- 最终增强 -->
<aop:after method="after" pointcut-ref="pointcut"/>
<!-- 异常抛出增强 -->
<aop:after-throwing method="afterThrowing" pointcut-ref="pointcut"/>
<!-- 环绕增强 -->
<aop:around method="around" pointcut-ref="pointcut"/>
<!-- 后置增强 -->
<aop:after-returning method="afterReturning" returning="result" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>

后置增强处理代码

public void afterReturning(Object result) {
log.info("后置增强:"+result);
}

环绕增强处理代码

public Object around(ProceedingJoinPoint jp) throws Throwable{
//先执行try外面的 第二次执行try
log.info("环绕增强!");
try {
Object result=jp.proceed();
log.info("环绕增强!");
return result;
} catch (Exception e) {
e.printStackTrace();
throw e;
}finally {
log.info("环绕增强执行完毕!");
}
}

如方法出现异常 结果如下

没有异常结果如下

这里顺序出现了异常,是环绕增强的问题去掉就好了

使用注解实现aop

增强处理如下
package cn;

import org.apache.log4j.Logger;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut; /**
*定义切面
*/
@Aspect
public class Hotel {
Logger log = Logger.getLogger(Hotel.class);
//定义公共的 匹配条件
@Pointcut("execution(public String havingDinner())")
public void pointcut() {}
@Before("pointcut()")
public void order() {
log.info("前置");
}
//这样也是可以的@Around("execution(public String havingDinner())")
@Around("pointcut()")
public Object around(ProceedingJoinPoint jp) throws Throwable{
//先执行try外面的 第二次执行try
log.info("环绕增强!");
try {
Object result=jp.proceed();
log.info("环绕增强!");
return result;
} catch (Exception e) {
e.printStackTrace();
throw e;
}finally {
log.info("环绕增强执行完毕!");
}
}
@After("pointcut()")
public void after() {
log.info("最终增强");
}
@AfterThrowing("pointcut()")
public void afterThrowing() {
log.info("最终增强");
System.err.println("异常抛出增强");
}
@AfterReturning(pointcut="pointcut()",returning="result")
public void afterReturning(Object result) {
log.info("后置增强:"+result);
}
}

不同的注解对应不同的增强,其中@Aspect是必不可少的,没有它将会识别不到该类中的增强处理,并且还不会报错
aop配置如下
<?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:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd ">
<bean id="people" class="cn.People" p:name="小明"/>
<context:component-scan base-package="cn"/>
<bean class="cn.Hotel"/>
<aop:aspectj-autoproxy/>
</beans>
base-package属性为扫描的路径我喜欢直接写所有包的“父亲”,它会自动扫描下面子包,也可以这样写 
<context:component-scan base-package="cn.dao,cn.pojo"/>
希望能大家有所帮助,如有写的不好的地方欢迎反馈

了解并使用springAOP(面向切面编程)的更多相关文章

  1. JavaWeb_(Spring框架)SpringAOP面向切面编程

    SpringAOP:面向切面编程(面向fifter编程) 通俗易懂术语:所有纵向重复的代码,我们提取成横向的代码 以下文章内容参考知乎:从0带你学习SpringAOP,彻底的理解AOP思想 传送门 1 ...

  2. SpringAOP 面向切面编程

    AOP的相关概念 AOP:全称是 Aspect Oriented Programming 即:面向切面编程. 简单的说它就是把我们程序重复的代码抽取出来,在需要执行的时候,使用动态代理的技术,在不修改 ...

  3. Spring-AOP面向切面编程

    AOP是面向切面编程,区别于oop,面向对象,一个是横向的,一个是纵向. 主要解决代码分散和混乱的问题. 1.概念: 切面:实现AOP共有的类 通知:切面类中实现切面功能的方法 连接点:程序被通知的特 ...

  4. SpringAOP面向切面编程

    Spring中三大核心思想之一AOP(面向切面编程): 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的 ...

  5. Spring--AOP(面向切面)编程

    AOP 切面就像一把菜刀,将Java处理业务流程进行分割,在分割处添加特定的业务处理.主要应用于声明事务.安全和缓存.在本文中,主要介绍两种切面的实现方法--Java配置和XML配置. Java配置 ...

  6. AOP面向切面编程的四种实现

     一.AOP(面向切面编程)的四种实现分别为最原始的经典AOP.代理工厂bean(ProxyFacteryBean)和默认自动代理DefaultAdvisorAutoProxyCreator以及Bea ...

  7. spring入门(四)【面向切面编程】

    开发过程中很多时候会用到日志.事务等操作,这些操作如果要写在业务代码中会相当麻烦,这时就会用到面向切面编程(AOP),AOP作为一种编程思想,和OOP有着不同的侧重点,面向对象侧重于万事万物皆对象,而 ...

  8. 面向切面编程AOP

    本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...

  9. Spring面向切面编程(AOP)

    1 spring容器中bean特性 Spring容器的javabean对象默认是单例的. 通过在xml文件中,配置可以使用某些对象为多列. Spring容器中的javabean对象默认是立即加载(立即 ...

随机推荐

  1. 【ACM】拦截导弹 - 0-1背包问题

    拦截导弹 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 某国为了防御敌国的导弹袭击,发展中一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到 ...

  2. git——解决“fatal: Authentication failed for 'https://github.com/balabala”

    平复一下心情,到底如何在github上将队友和owner的仓库连接?如何push代码到远程仓库???找了巨多教程,终于解决了~ 刚到公司不久,开始学着用git,在提交代码的时候怎么都提不上去! 解决办 ...

  3. JS——数组、==和===的区别

    创建数组的方式: 1) <script type='text/javascript'> var aRr = new Array(1,2,3,4,'abc',3) </script&g ...

  4. 016 3Sum Closest 最接近的三数之和

    Given an array S of n integers, find three integers in S such that the sum is closest to a given num ...

  5. 备份当前的ubuntu系统生成iso

    使用respin,步骤如下: sudo add-apt-repository ppa:sergiomejia666/respin sudo apt-get update sudo apt-get in ...

  6. Storm概念学习系列之Topology拓扑

    不多说,直接上干货!   Hadoop 上运行的是 MapReduce 作业,而在 Storm 上运行的是拓扑 Topology,这两者之间是非常不同的.一个关键的区别是:一个MapReduce 作业 ...

  7. <Android 应用 之路> 天气预报(四)

    前言 第二次尝试完成天气预报应用,与上次不同的是,个人感觉这次的Ui不那么丑陋,整体的实用性和界面效果,用户体验相较上一次有所提升,但是还是有很多地方需要完善. 这次使用到的内容比较丰富,包括聚合数据 ...

  8. 关于com工程依赖的一些总结

    作者:朱金灿 来源:http://blog.csdn.net/clever101 一是com组件工程的依赖设置.比如A这个组件工程要使用B组件工程的类,要如何设置呢?具体就是先把在A工程里加上B工程的 ...

  9. ansible基本操作

    ansible优点:redhat自带工具,可通过rpm或yum直接安装:客户端免安装:操作通过ssh验证操作:可以通过自定义hosts文件对可操作主机进行分类,方便批量操作 #ansible操作格式, ...

  10. jQuery-名称符号$与其他库函数冲突

    1.通过全名替代简写的方式来使用 jQuery jQuery("button").click(function(){ jQuery("p").text(&quo ...