Spring核心之AOP

SpringAOP

Spring AOP相关概念

Spring的AOP实现底层就是对上面的动态代理的代码进行了封装,封装后我们只需要对需要关注的部分进行代码编写,并通过配置的方式完成指定目标的方法增强。

  • Target(目标对象)
    要被增强的对象,一般是业务逻辑类的对象。

  • Proxy(代理)
    一个类被 AOP 织入增强后,就产生一个结果代理类。

  • Aspect(切面)
    表示增强的功能,就是一些代码完成的某个功能,非业务功能。是切入点和通知的结合。

  • Joinpoint(连接点)
    所谓连接点是指那些被拦截到的点。在Spring中,这些点指的是方法(一般是类中的业务方法),因为Spring只支持方法类型的连接点。

  • Pointcut(切入点)
    切入点指声明的一个或多个连接点的集合。通过切入点指定一组方法。被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。

  • Advice(通知/增强)所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。通知的类型:前置通知,后置通知,异常通知,最终通知,环绕通知。
    切入点定义切入的位置,通知定义切入的时间。

  • Weaving(织入).
    是指把增强应用到目标对象来创建新的代理对象的过程。 spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装载期织入。

    • 切面的三个关键因素:
      1、切面的功能–切面能干啥
      2、切面的执行位置–使用Pointcut表示切面执行的位置
      3、切面的执行时间–使用Advice表示时间,在目标方法之前还是之后执行。

AspectJ 对 AOP 的实现

对于 AOP 这种编程思想,很多框架都进行了实现。Spring 就是其中之一,可以完成面向切面编程。AspectJ 也实现了 AOP 的功能,且其实现方式更为简捷而且还支持注解式开发。所以,Spring 又将AspectJ 的对于 AOP 的实现也引入到了自己的框架中。
在 Spring 中使用 AOP 开发时,一般使用 AspectJ 的实现方式,AspectJ 是一个优秀面向切面的框架,它扩展了 Java 语言,提供了强大的切面实现。

注解方式实现AOP

开发阶段:关注核心业务和AOP代码

运行阶段:spring框架会在运行的时候将核心业务和AOP代码通过动态代理的方式编织在一起代理方式的选择:是否实现了接口:有接口就选择JDK动态代理;没有就选择CGLIB动态代理。

引入依赖

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
            <version>5.3.9</version>
        </dependency>

spring.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd
">
<!--  在beans中引入aop约束-->
    <context:component-scan base-package="com.zhou.service"/>
    <context:component-scan base-package="com.zhou.aop"/>
    <aop:aspectj-autoproxy proxy-target-class="true"/>
<!--    xml方式实现aop-->
    <aop:config>
        <aop:pointcut id="pt1" expression="execution(* com.zhou.service..*.*(..))"/>
        <aop:aspect ref="aop">
            <aop:before method="before" pointcut-ref="pt1"/>
            <aop:after-returning method="after" pointcut-ref="pt1" returning="result"/>
            <aop:after-throwing method="exception" pointcut-ref="pt1" throwing="ex"/>
            <aop:after method="myFinally" pointcut-ref="pt1"/>
        </aop:aspect>
    </aop:config>
</beans>

切面类

package com.zhou.aop;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

/**
 * 切面类
 */
@Component
@Aspect
public class Aop {
    //在方法执行之前被调用的通知
    public void before(JoinPoint jp){
        System.out.println("前置通知");
    }
    //在方法执行之后被调用的通知
    public void after(Object result){
        System.out.println("后置通知");
    }
    //在方法执行出现异常被调用的通知
    public void exception(Throwable ex){
        System.out.println("异常通知");
    }
    //无论是否出现异常都会被调用
    public void myFinally(){
        System.out.println("最终通知");
    }

}

核心业务类

package com.zhou.service;

import org.springframework.stereotype.Service;

/**
 * 核心业务类
 */
@Service
public class TeamService implements IService{
    @Override
    public void add(int id, String name) {
        System.out.println("TeamService-----add");
    }

    @Override
    public boolean update(int num) {
        System.out.println("TeamService-----update");
        return true;
    }
}

测试类

import com.zhou.service.IService;
import com.zhou.service.TeamService;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Mytest {
    @Test
    public void test1(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");
        TeamService teamService = (TeamService) applicationContext.getBean("teamService");
        teamService.add(1,"sas");
    }
}

测试结果:
在这里插入图片描述

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值