美文网首页
Spring之AOP

Spring之AOP

作者: 紫荆秋雪_文 | 来源:发表于2019-09-29 00:07 被阅读0次

一、装饰模式

装饰设计模式:在不必改变源代码基础上,动态的扩展一个对象的功能。它是通过创建一个包装对象,也就是包裹真实的对象。就是对已有对象进行功能的增强。

静态代理:

在程序运行前就已经存在代理类的字节码文件,代理对象和真实对象的关系在程序运行前就确定了。

动态代理:

动态代理类是在程序运行期间由JVM通过反射等机制动态的生成的,所以不存在代理类的字节码文件。代理对象和真实对象的关系是在程序运行时期才确定的。

静态代理优缺点:

优点:业务类只需要关注业务逻辑本身,保证了业务类的重要性。
缺点:

    1. 代理对象的某个接口只服务于某一种类型的对象,也就是说每一个真实对象都得创建一个代理对象
    1. 如果需要代理的方法很多,则要为每一种方法都进行代理处理
    1. 如果接口增加一个方法,除了所有实现类需要实现这个方法外,所有代理类也需要实现此方法。增加了代码维护的复杂度

二、AOP概念

1、AOP:Aspect oritention programming(面向切面编程)

2、AOP的目的:

AOP能够将那些与业务无关,却为业务模块所共同调用的逻辑或责任(例如事务处理、日志管理、权限控制等)封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性。

3、AOP的优势:

降低模块的耦合度、使系统容易扩展、更好的代码复用性

4、Spring的AOP使用动态代理实现:

  • 如果一个类实现了接口,那么spring就使用JDK的动态代理完成AOP;
  • 如果一个类没有实现接口,那么spring就是用cglib完成AOP;

5、AOP当中的概念:

  • 5.1、切入点(Pointcut):在哪些类,哪些方法上切入(where);
  • 5.2、增强(Advice):早期翻译为通知,在方法执行的什么时机(when:方法前/方法后/方法前后)做什么(what:增强的功能);
  • 5.3、切面(Aspect):切面=切入点+通知,通俗点就是:什么时机,什么地点,做什么!
  • 5.4、织入(Weaving):把切面加入到对象,并创建出代理对象的过程。(该过程由Spring来完成)。

三、XML配置AOP

1、jar包

  • spring-aop-5.1.0.RELEASE.jar
  • com.springsource.org.aopalliance-1.0.0.jar
  • com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

2、表示在哪些方法上增强——AspectJ(语言)

  • AspectJ切入点语法如下
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?    
            name-pattern(param-pattern)throws-pattern?)

翻译成中文:
execution(<访问修饰符>? <返回类型> <声明类型>? <方法名>(<参数>) <异常>?)
  • 在所有的业务层方法上做增强:
execution (* com.revanwang.pss.service.*Service.*(..))
AspectJ.png

3、配置AOP命名空间

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="http://www.springframework.org/schema/beans"     
    xmlns:context="http://www.springframework.org/schema/context"
    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/context
        http://www.springframework.org/schema/context/spring-context.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        ">
</beans>

4、配置AOP

<!-- 配置AOP: 1.切面: what 2.切入位置:where 3.切入时机:when -->
<aop:config>
    <aop:aspect ref="txManager"><!--what:增强了什么-->
        <!--where:哪些包下的哪些类中的哪些方法上增强-->
        <aop:pointcut expression="execution(* com._520it.aop.*Service.*(..))" id="txPoint" />
        <!--when:在方法的前/后增强-->
        <aop:before method="beginTransaction" pointcut-ref="txPoint" />
        <aop:after-returning method="commit" pointcut-ref="txPoint"/> 
        <aop:after-throwing method="rollback" pointcut-ref="txPoint"/>
    </aop:aspect>
</aop:config>

四、注解配置AOP

4.1:各种不同的增强:

  • aop:before(前置增强):在方法执行之前执行增强;
  • aop:after-returning(后置增强):在方法正常执行完成之后执行增强(中间没有遇到任何异常);
  • aop:throwing(异常增强):在方法抛出异常退出时执行增强代码;
  • aop:after(最终增强):在方法执行之后执行,相当于在finally里面执行;可以通过配置throwing来获得拦截到的异常信息
  • aop:around(环绕增强):最强大的一种增强类型。 环绕增强可以在方法调用前后完成自定义的行为,环绕通知有两个要求,
    - 1,方法必须要返回一个Object(返回的结果)
    - 2,方法的第一个参数必须是ProceedingJoinPoint(可以继续向下传递的切入点)


    Spring_TX.png

4.2:AOP相关的标签解析器

 <!-- 扫描包中的bean组件 -->
    <context:component-scan base-package=""/>
<!-- AOP的自动代理 -->
    <aop:aspectj-autoproxy/>

  • @Component("txManager")
  • @Aspect//<aop:aspect ref="txManager">:做什么
public class TransactionManager{ 
    //切入点
    //<aop:pointcut expression="execution(* com._520it.day2.aop_ann.*Service.*(..))" id="txPoint"/>
    @Pointcut("execution(* cn.itsource.day2.aop_ann.*Service.*(..))")
    public void txPoint(){}
    //前置增强:<aop:before method="beginTransaction" pointcut-ref="txPoint"/>
    @Before("txPoint()")
    public void beginTransaction(JoinPoint jp) {
        System.out.println("开启事务.....");
    }
    //后置增强:<aop:after-returning method="commit" pointcut-ref="txPoint"/> 
    @AfterReturning("txPoint()")
    public void commit() {
        System.out.println("提交事务.....");
    }
    //异常增强:<aop:after-throwing method="rollback" pointcut-ref="txPoint" throwing="ex"/>
    @AfterThrowing(value="txPoint()",throwing="ex")
    public void rollback(Throwable ex) {
        System.out.println(ex.getMessage());
        System.out.println("回滚事务.....");
    }
    //最终增加:<aop:after method="close" pointcut-ref="txPoint"/>
    @After("txPoint()")
    public void close() {
        System.out.println("关闭session.....");
    }
    //环绕增强:<aop:around method="around" pointcut-ref="txPoint"/>
    @Around("txPoint()")
    public Object around(ProceedingJoinPoint pjp) {
        System.out.println("开启事务.....");
        try {
            Object ret = pjp.proceed();//调用正在的业务方法
            System.out.println("提交事务.....");
            return ret;
        } catch (Throwable e) {
            System.out.println("回滚事务....."+e.getMessage());
        } finally {
            System.out.println("关闭session.....");
        }
        return null;
    }
}

建议使用XML配置AOP,通用,可维护性较高。

相关文章

网友评论

      本文标题:Spring之AOP

      本文链接:https://www.haomeiwen.com/subject/ehouuctx.html