Spring——AOP操作 AspectJ动态代理方式

有几天没有学习spring了,今天继续学习尚硅谷spring aop,讲的挺详细的,推荐去看看。

文章目录

  • 一、准备工作
    • 1、导入AspectJ依赖
    • 2、切入点表达式
  • 二 、配置文件实现
    • 1、创建类(作为目标对象),在类里面定义方法
    • 2、编写增强类,在增强类里面定义不同的通知
    • 3、配置注解信息
    • 4、配置通知信息
    • 5、运行结果
    • 6、注意事项

一、准备工作

1、导入AspectJ依赖

  1. 什么是AspectJ:AspectJ是一种用来实现aop操作的一个框架,它并不是Spring里面的,而是一种可以单独实现aop操作的独立的框架。Spring里面一般都是使用这个框架实现aop操作。
  2. 导入AspectJ依赖(maven依赖官网:https://mvnrepository.com)
        <dependency>
            <groupId>org.springframeworkgroupId>
            <artifactId>spring-aspectsartifactId>
            <version>${spring.version}version>
        dependency>

        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjtoolsartifactId>
            <version>1.9.5version>
        dependency>

        <dependency>
            <groupId>aopalliancegroupId>
            <artifactId>aopallianceartifactId>
            <version>1.0version>
        dependency>

        <dependency>
            <groupId>org.aspectjgroupId>
            <artifactId>aspectjweaverartifactId>
            <version>1.9.0version>
        dependency>

        <dependency>
            <groupId>cglibgroupId>
            <artifactId>cglibartifactId>
            <version>3.3.0version>
        dependency>

2、切入点表达式

  1. 什么是切入点表达式:用切入点表达式可以定位想要增强的方法的位置
  2. 具体语法:execution([权限修饰符] [返回类型] [类全路径 ] [ 方法名](参数列表))
  3. 假设我要增强com/example/dao/impl/StuDaoImpl下的select方法,那切入点表达式就是execution(* com.example.dao.impl.StuDaoImpl.select(…)),其中返回类型用表示代表任意的类型都行,public,private等都可以,权限修饰符可以省略不写,参数列表 . .表示任意参数。如果我要增强com/example/dao/impl/StuDaoImpl下面的全部方法,切入点表达式为execution( com.example.dao.impl.StuDaoImpl.(…)),如果要增强com/example/dao/impl包下面的全部类的全部方法,切入点表达式为execution( com.example.dao.impl. * .*(…))

二 、配置文件实现

实现步骤:

1、创建类(作为目标对象),在类里面定义方法

Spring——AOP操作 AspectJ动态代理方式_第1张图片

2、编写增强类,在增强类里面定义不同的通知

Spring——AOP操作 AspectJ动态代理方式_第2张图片

3、配置注解信息

(1)开启组件扫描
大致配置文件如下,这里和前面设置组件扫描一样,加一个context和aop的命名空间就行。


<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="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
                            http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                            ">

beans>

具体配置方法看下图,复制第一句,将它放到第2,3句的位置,然后前面分别加上 :context和:aop,再把后面bean的位置分别换成context和aop;然后复制第四句,放到第5,6句的位置,分别将5,6句后面的bean换成context 和 aop。
Spring——AOP操作 AspectJ动态代理方式_第3张图片

(2)开启组件扫描,注解代理对象和被代理对象
开启组件扫描只需要加入一个context:component-scan标签,这个标签可以将对应类的实例化通过注解方式加入IOC容器,而不用通过xml配置文件。到时候我们直接在IOC容器里面拿出类的实例化就行。base-package属性里面是你实例化类的包路径,我的两个类都在com.example包下。
在这里插入图片描述
注解方式如下,通过@Component()注解,详细注解可以看我另一篇博客。
Spring——AOP操作 AspectJ动态代理方式_第4张图片
在这里插入图片描述

(3)注解代理类
在你的代理类上面加上一个注释@Aspect ,spring就知道你这个类是代理类,就可以执行代理对象里面的方法了。
在这里插入图片描述

(4)开启生成对象
通过aop:aspecti-autoproxy标签,就可以通过找到有@Aspect注解的类,然后这个类就是代理类。
在这里插入图片描述

4、配置通知信息

一共有5种通知,不同的通知通过不同的注解实现。

  1. 前置通知:@Before(value = "execution(* com.example.dao.impl.StuDaoImpl.select(..))") value里面就是切入点表达式
  2. 后置通知:@After
  3. 异常通知:@AfterThrowing
  4. 环绕通知:@Around
  5. 最终通知: @AfterReturning

Spring——AOP操作 AspectJ动态代理方式_第5张图片

5、运行结果

代码:

    @Test
//    测试AspectJ注解方式
    public void proxyTest002(){
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext-AspectJ.xml");

        StuDaoImpl stuDao = applicationContext.getBean("stuDao", StuDaoImpl.class);

        stuDao.select();
    }
}

Spring——AOP操作 AspectJ动态代理方式_第6张图片

6、注意事项

使用AspectJ所代理的类不能实现其它接口,因为aop动态代理一共有两种方法:JDK动态代理和CGLIB动态代理,这里用到的是CGLIB动态代理,它是没有实现接口的,我最开始没有理解这个问题,让被代理的类实现接口,然后一直报错org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'stuDao' is expected to be of type 'com.example.dao.impl.StuDaoImpl' but was actually of type 'com.sun.proxy.$Proxy25'后面把接口实现去掉之后,就可以实现了。
修改之前:
在这里插入图片描述
修改之后:
在这里插入图片描述

你可能感兴趣的:(Spring,java,spring,spring,boot)