走过路过不要错过,有钱捧个钱场,没钱捧个人场. 欢迎欢迎.|

志旋

园龄:4年10个月粉丝:5关注:1

Spring Aop详解

Spring aop详解

spring aop 的概述

  • aop 面向切面(方面)编程,扩展功能不修改源代码的实现。
  • aop采取的是横向抽取机制,取代了传统纵向继承体系重复代码(性能监视、事物管理、安全检查、缓存)

Aop 的原理

动态代理解析图

public class User {
  //添加用户的方法
    public void add() {}
    public void update() {}
    public void delete() {}
    public void findAll() {}
    /**
     * 扩展功能
     * 1.添加用户之后,添加日志功能
     * 2.添加之后,记录什么时间添加了那个用户
     */
}
  • 切面(Aspect):
    一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在Spring AOP中,切面可以使用基于模式或者基于@Aspect注解的方式来实现。

  • 连接点(Joinpoint): 类里面哪些方法可以被增强的,这些方法称为连接点

  • 通知(Advice)
    实际增强的逻辑,称为增强,比如扩展日志的功能,这个日志功能叫做通知,也称为增强
    通知称为:前置通知,后置通知,最终通知,环绕通知

  • 切入点(Pointcut)
    在类里面有很多方法被增强,比如实际操作中,只是增强了类里面的add方法和update方法,实际增强的方法称为切入点。

  • 引入(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框架一样,在运行时完成织入。

Aop 的操作

在spring里面进行aop操作,进行aspectj实现
  • aspectjz不是spring的一部分,spring使用aspectj一起使用进行aop操作。
  • spring2.0以后新增了Aspectj支持
使用aspect实现aop有两种方式
  • 基于aspectj的xml配置
  • 基于aspectj的注解方式

(1)基于配置实现SpringAop

使用execution(<访问修饰符?<返回类型><方法名>(<参数>)<异常>)

  • execution(* con.springaop.Book.add(…))
  • execution(* con.springaop.Book.*(…))book的所有返回值类型的所有方法
  • execution(* .(…))所有路径所有返回值的所有方法
  • execution(* .save(…)) 配置所有以save开头的方法

aop xml配置文件

<?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.xsd">
    <!--配置对象 -->
    <bean id="book" class="springaop.book.Book"/>
    <bean id="myBook" class="springaop.book.MyBook"/>
    <!--配置aop-->
    <aop:config>
        <!-- 配置切入点-->
        <aop:pointcut id="pointcut1" expression="execution(* springaop.book.*.*(..))"/>
        <!-- 配置切面 把增强应用方法上面去 -->
        <aop:aspect id="aspect" ref="myBook">
            <aop:before method="beforeAdvice" pointcut-ref="pointcut1"/>
            <aop:after method="afterAdvice" pointcut-ref="pointcut1"/>
            <aop:around method="aroundAdvice" pointcut-ref="pointcut1"/>
        </aop:aspect>
    </aop:config>
</beans>
package springaop.book;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyBook {

    public void beforeAdvice() {
        System.out.println("前置通知");
    }
    public void afterAdvice() {
        System.out.println("后置通知");
    }
    /**
     * proceedingJoinPoint是一个切入点,被增强的方法
     * @param proceedingJoinPoint
     * @throws Throwable
     */
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知");
        proceedingJoinPoint.proceed();
        System.out.println("环绕通知1");
    }
    public void finalAdvice() {
        System.out.println("最终通知");
    }
    public void execptionAdvice() {
        System.out.println("异常通知");
    }
}

这里一定要注意环绕通知,如果环绕通知只是写逻辑操作,没有调用proceedingJoinPoint.proceed();方法是不会调用方法的,所以需要调用切入点的该方法

(2)基于注解实现SpringAop

这里一定要在配置文件开启aop代理还有开启注解

@Aspect
@Component("bookAspect")
public class BookAspect {
    @Pointcut(value = "execution(* springaop2.Book.*(..))")
    public void pointCut() {
        System.out.println("-----pointCut------");
    }
    @Before("pointCut()")
    public void beforeAdvice() {
        System.out.println("-----beforeAdvice-----");
    }
    @After("pointCut()")
    public void afterAdvice() {
        System.out.println("-----afterAdvice-----");
    }
    @Around("pointCut()")
    public void aroundAdvice(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("-----start--aroundAdvice---");
        proceedingJoinPoint.proceed();
        System.out.println("-----end--aroundAdvice---");
    }
}

本文作者:志旋

本文链接:https://www.cnblogs.com/wuzhixuan/p/12890670.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   志旋  阅读(59)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起