SSM-spring-AOP

spring-AOP

AOP(Aspect Oriented Programming),即面向切面编程

目录

spring-AOP

AOP 的特性

AOP的工作流程

AOP执行流程的具体案例

AOP切入点表达式

关键字 execution

书写规范、要求

环绕通知

案列——面向切面编程

AOP总结

补充内容:基于XML schema的AOP

具体案例,代码演示:


AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过 OOP 允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在 OOP 设计中,它导致了大量代码的重复,而不利于各个模块的重用。

OOP 面向对象,允许开发者定义纵向的关系,但并适用于定义横向的关系,导致了大量代码的重复,而不利于各个模块的重用。

AOP 技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名 为" Aspect ",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

AOP 的特性


切面(Aspect)
被抽取的公共模块,可能会横切多个对象。 在Spring AOP中,切面可以使用通用类或者在普通类中以@AspectJ注解来实现。

连接点(Join point)
指方法在Spring AOP中,一个连接点总是代表一个方法的执行。 

通知(Advice)
在切面的某个特定的连接点(Join point)上执行的动作。通知有各种类型,其中包括“around”、“before”和“after”等通知。许多AOP框架,包括Spring,都是以拦截器做通知模型,并维护一个以连接点为中心的拦截器链。

切入点(Pointcut)
切入点是指我们要对哪些Join point进行拦截的定义。通过切入点表达式,指定拦截的方法,比如指定拦截add*、search*。

引入(Introduction)
声明额外的方法或者某个类型的字段。Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象。例如,你可以使用一个引入来使bean实现IsModified接口,以便简化缓存机制。在不修改代码的前提下,引入可以在运行期为类动态地添加一些方法或字段。

目标对象(Target Object)
被一个或者多个切面(aspect)所通知(advise)的对象。也有人把它叫做被通知(adviced)对象。既然Spring AOP是通过运行时代理实现的,这个对象永远是一个被代理(proxy)对象。

织入(Weaving)
指把增强应用到目标对象来创建新的代理对象的过程。Spring是在运行时完成织入。

AOP的工作流程

如下为 AOP的工作流程 + 理解的核心概念:

AOP执行流程的具体案例

补充:MVC理解点:

过程理解:

AOP切入点表达式

关键字 execution

书写规范、要求

环绕通知

——注解@Around

关于如下通知为啥要返回对原始操作的调用结果的理解:


Object:表示兼容

这里的原理就是动态代理的原理,杨超越唱完歌要说谢谢,这个谢谢代理要给他返回出去观众才能收到:

代理对象的理解:

案列——面向切面编程

切面=切点+通知

入门案例:

AOP总结

切面=切点+(绑定)通知

补充内容:基于XML schema的AOP

具体案例,代码演示:

(  不常用,培养自己的逻辑能力!)

  UserDao:

package com.baowenli.demo03;
public interface UserDao {
    public void insert();
    public void delete();
    public void update();
    public void select();
}

UserDaoImpl:  

package com.baowenli.demo03;

public class UserDaoImpl implements UserDao {
    public void insert() {
        System.out.println("添加用户信息");
    }
    public void delete() {
        System.out.println("删除用户信息");
    }
    public void update() {
        System.out.println("更新用户信息");
    }
    public void select() {
        System.out.println("查询用户信息");
    }
}

XmlAdvice:    通知/增强

package com.baowenli.demo03;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class XmlAdvice {
   // 前置通知
    public void before(JoinPoint joinPoint){
        System.out.print("这是前置通知!");
        System.out.print("目标类是:"+joinPoint.getTarget());
        System.out.println(",被织入增强处理的目标方法为:"+
               joinPoint.getSignature().getName());
    }
    //返回通知
    public void afterReturning(JoinPoint joinPoint){
        System.out.print("这是返回通知(方法不出现异常时调用)!");
        System.out.println("被织入增强处理的目标方法为:"+
                joinPoint.getSignature().getName());
    }
    /**
     * 环绕通知
     * ProceedingJoinPoint 是JoinPoint子接口,表示可以执行目标方法
     * 1.必须是Object类型的返回值 ————表示兼容
     * 2.必须接收一个参数,类型为ProceedingJoinPoint
     * 3.必须throws Throwable
     */
    public Object around(ProceedingJoinPoint point)throws Throwable{
        System.out.println("这是环绕通知之前的部分!");
        //调用目标方法
        Object object=point.proceed();
        System.out.println("这是环绕通知之后的部分!");
        return object;
    }
    //异常通知
    public void afterException(){
        int a=1/0;
        System.out.println("异常通知!");
    }
    //后置通知
    public void after(){
        System.out.println("这是后置通知!");
    }
}

applicationContext.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 -->
    <bean name="userDao" class="com.baowenli.demo03.UserDaoImpl"/>
    <bean name="xmlAdvice" class="com.baowenli.demo03.XmlAdvice"/>

    <!--靠逻辑:配置AOP————
       1. 指定所有的切点,id不重复
       2. 你要配置的是哪个切面,引用出来!
       3. 前置/环绕增强,具体前置/环绕增强的方法,以及他的切入点!
     -->
    <!-- 配置Spring AOP-->

    <aop:config>
        <!-- 指定切点 -->
        <aop:pointcut id="pointcut" expression="execution(*
        com.baowenli.demo03.UserDaoImpl.*(..))"/>
        <!--指定切面  -->
        <aop:aspect ref="xmlAdvice">
            <!--指定前置通知-->
            <aop:before method="before" pointcut-ref="pointcut"/>
            <!--指定返回通知-->
            <aop:after-returning method="afterReturning" pointcut-ref="pointcut"/>

            <!--指定环绕方式-->
            <aop:around method="around" pointcut-ref="pointcut"/>
            <!-- 指定异常通知 -->
            <aop:after-throwing method="afterException"
                                pointcut-ref="pointcut"/>
            <!-- 指定后置通知 -->
            <aop:after method="after" pointcut-ref="pointcut"/>
        </aop:aspect>
    </aop:config>
</beans>

applicationContext-Anno.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 -->
    <bean name="userDao" class="com.baowenli.demo03.UserDaoImpl"/>
<!--    <bean name="AnnoAdvice" class="com.baowenli.demo04.AnnoAdvice"/>-->
    <!-- 开启@aspectj的自动代理支持 -->
    <aop:aspectj-autoproxy/>
</beans>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值