欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringAOP面向切面编程

程序员文章站 2022-04-24 19:05:38
Spring中三大核心思想之一AOP(面向切面编程): 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内 ......

spring中三大核心思想之一aop(面向切面编程):

在软件业,aop为aspect oriented programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。aop是oop的延续,是软件开发中的一个热点,也是spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用aop可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
(更深入请百度)
spring 2.0在aop上有很大的改进。首先,aop xml的配置更加简单了,spring2.0引入了新的模式,支持定义从常规java对象中发展来的切面,充分利用了aspectj切入点语言,提供了完整类型的advice(也就是没有多余转换和object[] 参数操作)。另外,得意于annotation的发展,spring2.0提供了对@aspectj切面的支持,这些切面可以在aspectj与spring aop*享,需要的仅仅是简单的配置。
 
aop机制?
使用aop仍然需要修改所有的方法,但是修改这个方法的过程由spring来帮我们完成
 
 aop通知类型:
  前置通知,关键词before。指的是在一个方法执行前通知。
   后置通知,关键词after。指的是在一个方法执行后进行通知。
   环绕通知,关键词around。值的是在一个方法之前与之后执行进行通知。
   异常抛出后通知,throw。在一个方法执行过程中之后并且抛出异常进行通知。
操作代码记录:
  
<?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.xsd
    http://www.springframework.org/schema/aop 
    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd">
    <!-- 定义bean -->
    <bean id="stuservice" class="com.lxit.aop.service.studentservice" />
    <!-- aop配置 -->
    <!-- 添加aspect的bean -->
    <bean id="logaspect" class="com.lxit.aop.aspect.logaspect" />
    <aop:config>
        <!-- 定义一个pointcut -->
        <aop:pointcut id="servicepointcut" 
        expression="execution(* com.lxit.aop.service.*.*(..))" />
        <!-- 定义aspect,引用生成的aspectbean 并指定pointcut 和 method-->
        <aop:aspect id="aspect1" ref="logaspect">
            <aop:after pointcut-ref="servicepointcut" method="logadd" />
        </aop:aspect>
    </aop:config>
</beans>
public static void main(string[] args) {
applicationcontext ac = 
    new classpathxmlapplicationcontext("spring.xml");
studentservice service = (studentservice) ac.getbean("stuservice");
service.add();
service.getstudent();
}

异常抛出增强:

异常抛出增强的特点是在目标方法抛出异常时织入增强处理,
但是异常处理一般会需要获取异常参数。
在配置文件中添加异常处理的aspect。
使用<aop:after-throwing来进行异常织入。

public class exceptionaspect {
public void exceptionlog(exception e){
    system.out.println("发生异常,写入日志。" + e.getmessage());
}
}
<bean id="exceptionaspect" class="com.lxit.aop.aspect.exceptionaspect" />
<aop:config>
<!-- 定义一个pointcut -->
<aop:pointcut id="servicepointcut" 
    expression="execution(* com.lxit.aop.service.*.*(..))" />
<!-- 定义aspect,引用生成的aspectbean 并指定pointcut 和 method-->
<aop:aspect id="aspect2" ref="exceptionaspect">
    <!-- 表示当程序发生异常后才织入 -->
    <aop:after-throwing method="exceptionlog" 
         pointcut-ref="servicepointcut" throwing="e"/>
</aop:aspect>
</aop:config>

环绕增强:

 

环绕增强在目标方法的前后都可以织入增强处理
环绕增强是功能最强大的增强处理,spring把目标方法的控制权全部交给了它
在环绕增强处理中,可以获取或修改目标方法的参数、返回值,可以对它进行异常处理,甚至可以决定目标方法是否执行

 

public class aroundlogger {
    public object aroundlogger(proceedingjoinpoint jp) throws throwable { … } 
}
<bean id="thelogger" class="aop. aroundlogger"></bean>
<aop:config>
    <aop:pointcut id="pointcut" expression="execution(* biz.iuserbiz.*(..))" />
    <aop:aspect ref="thelogger">
        <aop:around  method="aroundlogger"  pointcut-ref="pointcut" />
    </aop:aspect>
</aop:config>

 

五中织入方式的区别:
<aop:before …>:在目标方法调用之前织入。
只要before方法执行完成,目标方法总会被调用,但before可以通过抛出异常来阻止目标方法执行,before不能访问目标方法的返回值。

<aop:after…>:在目标方法调用之后织入。
after不能组织目标方法的执行,after不能访问目标方法的返回值。

<aop:after-throwing..>:抛出异常时织入。如果指定throwing必须指定一个异常参数,增强方法中必须和此参数同名,类型必须大于该异常类型。

<aop:after-returning…>:在目标方法成功执行之后织入。
after-returning:不能阻止目标方法的执行,可以访问目标方法的返回值,但不能修改。

<aop:around…>:在目标方法调用之前和调用之后织入。它的处理方法必须包含一个proceedingjoinpoint形参。
aop:around:可以组织目标方法的执行,可以访问目标方法的返回值,可以修改返回值。

以上增强器都可以指定args来指定参数

 

在struts2,hibernate,spring整合中就可以看到一种很好的效果。

在serivce层定义成一个切点在执行操作前可以开启一系列操作,比如写入日志,事务等操作是一种典型的案例。

 

 

aop使用场景

aop用来封装横切关注点,具体可以在下面的场景中使用:

authentication 权限 caching 缓存 context passing 内容传递 error handling 错误处理 lazy loading 懒加载

debugging  调试 logging, tracing, profiling and monitoring 记录跟踪 优化 校准 performance optimization 性能优化

persistence  持久化 resource pooling 资源池 synchronization 同步 transactions 事务