SpringAOP(动态代理)

基本概念

1.连接点 :可以增强的方法叫做连接点(现在的理解是自己创建的类都是链接点 以后学深入了在来修改)
2.切入点 : 实际被增强的方法
3.通知 :方法的增强部分叫做通知(具体通知在后面写)
4.切面:就是动作(不太懂过后补上)

在这里插入图片描述
在这里插入图片描述

通知类型

前置通知 @Before(value = “execution( *** )”)
环绕通知 @Around(value = “execution( *** )”)
异常通知 @AfterThrowing(value = “execution( *** )”)
返回通知 @AfterReturning(value = “execution( *** )”)
最终通知 @After(value = “execution(* execution( *** )”)

基于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="user" class="com.xzh.test.User"></bean>

    <!--切面对象-->
    <bean id="userAspectJ" class="com.xzh.test.UserAspectJ"></bean>

    <!--配置织入:告诉spring框架 哪些方法(切点)需要进行哪些增强(前置、后置...)-->
    <aop:config>
        <!--声明切面-->
        <aop:aspect ref="userAspectJ">
            <!--抽取切点表达式-->
            <aop:pointcut id="myPointcut" expression="execution(* com.xzh.test.User.add(..))"></aop:pointcut>
            <!--切面:切点+通知-->
            <!--<aop:before method="before" pointcut="execution(* com.xzh.test.User.add(..))"/>-->
            <!--<aop:before method="before" pointcut="execution(* com.xzh.test.User.add(..))"/>
            <aop:after-returning method="afterReturning" pointcut="execution(* com.xzh.test.User.add(..))"/>-->
            <!--<aop:around method="around" pointcut="execution(* com.xzh.test.User.add(..))"/>
            <aop:after-throwing method="afterThrowing" pointcut="execution(* com.xzh.test.User.add(..))"/>
            <aop:after method="after" pointcut="execution(* com.xzh.test.User.add(..))"/>-->
            <aop:around method="Around" pointcut-ref="myPointcut"/>
            <aop:after method="After" pointcut-ref="myPointcut"/>

        </aop:aspect>
    </aop:config>

</beans>

基于配置类方法:

和之前的差别有 首先要在配置类上加上@EnableAspectJAutoProxy表示开启动态代理
增强类(动态代理类) 要加上@Aspect 声明他是一个增强类
其次每种通知 都要加上 value 配置增强的是哪个类或方法

1.首先创建Spring配置类

@Configuration
@ComponentScan(basePackages = {"com.xzh.test"})
@EnableAspectJAutoProxy
public class SpringConfig {
}

2.增强类的代码和被增强类:

package com.xzh.Spring5.AspectJ;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Repository;

/**
 * @Author XuZhuHong
 * @CreateTime 2021/5/19 10:35
 * 主函数
 */
public class TestAop {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);
        User user = context.getBean("user", User.class);
        user.add();
    }
}



/**
 * 重点****************************************************************************
 * UserAspectJ类  (增强)
 */
@Component//创建对象
@Aspect//声明这是一个增强类(动态代理)
        // 如果有多个增强类增强一个方法 用@Order(数字)注解来设置优先级  数字越小越先执行
class UserAspectJ {

    //这是用Pointcut注解 把切入点提取出来方便复用
    // * 代表所有权限 后面的 com.**** 代表要增强的方法 add里面的 .. 表示参数列表
    @Pointcut(value = "execution(* com.xzh.Spring5.AspectJ.User.add(..))")
    public void Pointcut(){}
    //也可以用定义常量的方式来填写
    //   final String execution="execution(* com.xzh.Spring5.AspectJ.User.add(..))";
	//如果要增强多个方法:写法如下:
 //  @Pointcut(value = "execution(* com.xzh.test.User.add(..)) || execution(* com.xzh.test.User.delete(..))")



    //通知执行的顺序如下
    //每一个通知里面的value必须要有  现在这里面用的是调用配置的方法来填写value

    //下面这一句就是说明 增加前置通知 格式必须这样写
    @Before(value = "Pointcut()")
    //等价于:@Before(value = "execution(* com.xzh.Spring5.AspectJ.User.add(..))")
    public void Before() {
        System.out.println("UserAspectJ before执行了");
    }

    //环绕通知  就是在方法前执行和方法后执行  在执行前后需要调用本体方法
    //这个方法通知是有点特殊的 必须要传入一个参数  这个参数是用来执行本体方法的
    @Around(value ="Pointcut()")
    public void Around(ProceedingJoinPoint pjp) throws Throwable {
        System.out.println("UserAspectJ Around前 执行了");
        //调用proceed()来执行原来的方法
        pjp.proceed();
        System.out.println("UserAspectJ Around后 执行了");
    }


    //当程序有异常会执行的通知
    @AfterThrowing(value ="Pointcut()")
    public void AfterThrowing() {
        System.out.println("UserAspectJ AfterThrowing 执行了");
    }

    //返回通知  如果AfterThrowing通知执行  这个则不会执行
    @AfterReturning(value = "Pointcut()")
    public void AfterReturning() {
        System.out.println("UserAspectJ AfterReturning 执行了");
    }

    //最终通知 在本体方法执行后的执行方法  这个无论如何都会执行
    @After(value = "Pointcut()")
    public void After() {
        System.out.println("UserAspectJ after执行了");
    }


}





/************************************************************************************
 * User类   (被增强)
 */
@Repository//创建对象的注解
 class User {
    public void add(){
        System.out.println("User  add 执行了");
    }
}

运行结果
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值