Spring AOP 学习笔记

来源:互联网 发布:软件研发人员绩效考核 编辑:程序博客网 时间:2024/05/16 11:32

1、通过xml配置aop

1.1 新建一个aop的切面类

@Aspectpublic class MkztAspect {    private static final Logger log = LogManager.getLogger(MkztAspect.class);    public void mkztAround(JoinPoint point) {        System.out.print("开始执行模块状态切面.");        MethodInvocationProceedingJoinPoint b = (MethodInvocationProceedingJoinPoint) point;        Object obj = b.getTarget();        Object[] args = point.getArgs();        String pointStr = b.toString();        String func = pointStr.substring(pointStr.indexOf("(") + 1, pointStr                .indexOf(")"));        try {            if ("rwFxMkzt".equals(func)) {                List<Map> mkztList = MkjdgzUtils.getMkzt(args);                if (mkztList != null && mkztList.size() > 0) {                    MkjdgzUtils.setMkzt(mkztList);                }            }            if ("setModuleMkztBaseOnCslb".equals(func)) {                String lc = StringUtil.toString(args[0]);                List<Map> moduleids = (List<Map>) args[1];                MkjdgzUtils.setModuleMkztBaseOnCslb(lc, moduleids);            }            if ("updateMkztBaseOnCslxWhenCstg".equals(func)) {                String cslx = StringUtil.toString(args[0]);                String moduleId = StringUtil.toString(args[1]);                MkjdgzUtils.updateMkztBaseOnCslxWhenCstg(cslx, moduleId);            }            if ("updateMkztBaseOnCslxWhenCsbtg".equals(func)) {                String cslx = StringUtil.toString(args[0]);                String moduleId = StringUtil.toString(args[1]);                MkjdgzUtils.updateMkztBaseOnCslxWhenCsbtg(cslx, moduleId);            }            if ("sbUpdateMkzt".equals(func)) {                String ddid = StringUtil.toString(args[0]);                String xmid = StringUtil.toString(args[1]);                MkjdgzUtils.sbUpdateMkztSetHistory(ddid, xmid);            }        } catch (Throwable e) {            log.error("模块状态切面类执行方法异常.");            e.printStackTrace();        }        try {            b.proceed();//执行代理的方法        } catch (Throwable e) {            e.printStackTrace();        }    }}
<?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"    xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:util="http://www.springframework.org/schema/util"    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-2.0.xsd"    default-autowire="byName" default-lazy-init="true">    <!-- 支持 @AspectJ 标记-->    <aop:aspectj-autoproxy />    <!-- 以AspectJ方式 定义 AOP -->    <!-- 测试模块状态aop -->    <bean id="mkztAspect" class="com.hnisi.scpt.gzl.mkjdgz.aop.MkztAspect">    </bean>    <aop:config proxy-target-class="true">        <!-- 要监控的路径 多个以||分隔开-->        <aop:pointcut id="mkztUpdate"            expression="execution(* com.hnisi.scpt.gzl.mkjdgz.service.MkztService.*(..))" />        <aop:aspect id="aopAspect" ref="mkztAspect">            <!--模块状态更新环绕通知 -->            <aop:around pointcut-ref="mkztUpdate" method="mkztAround" />        </aop:aspect>    </aop:config></beans>

新建一个applicationContext-aop.xml文件,配置的内容写在aop:config标签下,这里只配置了一个环绕通知 aop:around

1,首先把所有原始对象的bean配置好
2,然后把所有切面bean配置好,配置切面的bean 的id与切面类的映射。
3,配置aop
(1)配置切点:关系到哪些方法执行时会调用相关切面的通知。切点先配置好,一会儿留着引用。
(2)配置每一个切面:
a。配置切面bean的id与order切面优先级的映射,以及切面内的各个通知。
b。配置各个切面内部的通知与切点的映射,切点以引用方式给出。
面向切面编程(AOP)通过提供另外一种思考程序结构的途经来弥补面向对象编程(OOP)的不足。在OOP中模块化的关键单元是类(classes),而在AOP中模块化的单元则是切面。切面能对关注点进行模块化,例如横切多个类型和对象的事务管理。(在AOP术语中通常称作横切(crosscutting)关注点。)
AOP框架是Spring的一个重要组成部分。但是Spring IoC容器并不依赖于AOP,这意味着你有权利选择是否使用AOP,AOP做为Spring IoC容器的一个补充,使它成为一个强大的中间件解决方案。
Spring 2.0的AOP
Spring 2.0允许用户选择使用更简单、更强大的基于模式或@AspectJ注解的方式来自定义切面。这两种风格都支持所有类型的通知(advice)和AspectJ的切入点语言,虽然实际上仍然使用Spring AOP进行织入(Weaving)。
本章主要讨论Spring 2.0对基于模式和基于@AspectJ的AOP支持。Spring 2.0完全保留了对Spring 1.2的向下兼容,下一章将讨论Spring 1.2 API所提供的底层的AOP支持。
AOP在Spring Framework中的作用
提供声明式企业服务,特别是为了替代EJB声明式服务。最重要的服务是声明性事务管理。
允许用户实现自定义切面,用AOP来完善OOP的使用。
如果你只打算使用通用的声明式服务或者封装好的声明式中间件服务,例如缓冲池(pooling),那么你不必与Spring AOP直接打交道,并且本章的大部分内容可以跳过了。
6.1.1. AOP概念
首先让我们从一些重要的AOP概念和术语开始。这些术语不是Spring特有的。不过AOP术语并不是特别的直观,如果Spring使用自己的术语,将会变得更加令人困惑。
切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式)或者基于@Aspect注解的方式来实现。
连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调用的时候或者处理异常的时候。在Spring AOP中,一个连接点总是表示一个方法的执行。
通知(Advice):在切面的某个特定的连接点上执行的动作。其中包括了“around”、“before”和“after”等不同类型的通知(通知的类型将在后面部分进行讨论)。许多AOP框架(包括Spring)都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。
切入点(Pointcut):匹配连接点的断言。通知和一个切入点表达式关联,并在满足这个切入点的连接点上运行(例如,当执行某个特定名称的方法时)。切入点表达式如何和连接点匹配是AOP的核心:Spring缺省使用AspectJ切入点语法。
引入(Introduction):用来给一个类型声明额外的方法或属性(也被称为连接类型声明(inter-type declaration))。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用引入来使一个bean实现IsModified接口,以便简化缓存机制。
目标对象(Target Object): 被一个或者多个切面所通知的对象。也被称做被通知(advised)对象。 既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxied)对象。
AOP代理(AOP Proxy):AOP框架创建的对象,用来实现切面契约(例如通知方法执行等等)。在Spring中,AOP代理可以是JDK动态代理或者CGLIB代理。
织入(Weaving):把切面连接到其它的应用程序类型或者对象上,并创建一个被通知的对象。这些可以在编译时(例如使用AspectJ编译器),类加载时和运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。
通知类型:
前置通知(Before advice):在某连接点之前执行的通知,但这个通知不能阻止连接点之前的执行流程(除非它抛出一个异常)。
后置通知(After returning advice):在某连接点正常完成后执行的通知:例如,一个方法没有抛出任何异常,正常返回。
异常通知(After throwing advice):在方法抛出异常退出时执行的通知。
最终通知(After (finally) advice):当某连接点退出的时候执行的通知(不论是正常返回还是异常退出)。
环绕通知(Around Advice):包围一个连接点的通知,如方法调用。这是最强大的一种通知类型。环绕通知可以在方法调用前后完成自定义的行为。它也会选择是否继续执行连接点或直接返回它自己的返回值或抛出异常来结束执行。
环绕通知是最常用的通知类型。和AspectJ一样,Spring提供所有类型的通知,我们推荐你使用尽可能简单的通知类型来实现需要的功能。例如,如果你只是需要一个方法的返回值来更新缓存,最好使用后置通知而不是环绕通知,尽管环绕通知也能完成同样的事情。用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的错误。比如,你不需要在JoinPoint上调用用于环绕通知的proceed()方法,就不会有调用的问题。
在Spring 2.0中,所有的通知参数都是静态类型,因此你可以使用合适的类型(例如一个方法执行后的返回值类型)作为通知的参数而不是使用Object数组。
通过切入点匹配连接点的概念是AOP的关键,这使得AOP不同于其它仅仅提供拦截功能的旧技术。 切入点使得通知可以独立对应到面向对象的层次结构中。例如,一个提供声明式事务管理 的环绕通知可以被应用到一组横跨多个对象的方法上(例如服务层的所有业务操作)。

0 0
原创粉丝点击