前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring框架(六)SpringAOP的介绍,Aspectj方式实现,注解方式

Spring框架(六)SpringAOP的介绍,Aspectj方式实现,注解方式

作者头像
一写代码就开心
发布2021-07-08 15:05:52
3820
发布2021-07-08 15:05:52
举报
文章被收录于专栏:java和python

目录

SpringAOP的Aspectj方式实现

前提

实现功能的扩展,可以在springAop下有一个这个方式进行实现。这个就是Aspectj.

之前的前置通知那些操作,就是SchemaBase方式实现功能的扩展。 现在也是实现功能的扩展,只是用不同的方式,现在的方式是Aspectj。

之前的方式有问题:

目前我们已经能够使用SpringAOP的SchemaBased方式来实现功能扩展。在使用SchemaBased方式实现功能扩展时,发现一个扩展代码就需要声明对应的实现了指定的接口的类,这样造成代码的结构体系过于繁杂。一个通知一个类。

解决:

在一个类中声明所有的通知方法。这样又会造成Spring容器无法区分该类中的方法那些是前置,那些是后置,那些是环绕,那些是异常了,怎么办?在配置文件中的切面配置中,指明哪些方法是前置,哪些是后置即可。

实现:

SpringAOP的AspectJ方式

SpringAOP的SchemaBased方式来实现功能扩展,需要使用接口,spring容器是需要通过接口才可以知道哪些是前置通知,哪些是后置通知。

现在使用Aspectj这个方式,我们就可以直接在xml里面告诉spring容器,哪些是前置通知,哪些是后置通知。

使用

我们现在就可以将很多的通知都写在一个类里面,并且不需要继承其他的接口。

将这个类需要在xml里面进行配置,并且需要在配置规则里面告诉spring容器,哪些是前置,哪些是后置。

代码语言:javascript
复制
public class MyAdvice {
    //前置通知
        public void before(String name,int age){
            System.out.println("我是前置通知"+name+age);
        }
    /*//后置通知
        public void after(){
            System.out.println("我是后置通知");
        }
    //环绕通知

参数必须是这样,这个是给spring看的
        public void myRound(ProceedingJoinPoint pp) throws Throwable {
            //环绕前
            System.out.println("环绕-前");
            //放行
            Object proceed = pp.proceed();
            //环绕后
            System.out.println("环绕-后");
        }
    //异常通知
        public void myThrow(Exception ex){
            System.out.println("我是异常通知:"+ex.getMessage());
        }*/
代码语言:javascript
复制
    <!--配置学生的bean-->
        <bean id="stu" class="com.pojo.Student"></bean>
        <!--配置通知bean-->
        <bean id="advice" class="com.advice.MyAdvice"></bean>
        <!--配置组装规则-->
        <aop:config>
ref这个属性就是告诉从哪一个类里面找方法
            <aop:aspect ref="advice"><!--声明通知bean的ID-->
                <!--声明切点-->
                <aop:pointcut id="mp" expression="execution(* com.pojo.Student.testStudent(String,int)) and args(name,age)"/>
                <!--前置通知-->
                <aop:before method="before"  pointcut-ref="mp" arg-names="name,age"></aop:before>
                <!--&lt;!&ndash;后置通知&ndash;&gt;
                <aop:after-returning method="after" pointcut-ref="mp"></aop:after-returning>
                &lt;!&ndash;环绕通知&ndash;&gt;
                <aop:around method="myRound" pointcut-ref="mp"></aop:around>
                &lt;!&ndash;异常通知&ndash;&gt;
throwing写的是异常通知的形参名字
                <aop:after-throwing method="myThrow" pointcut-ref="mp" throwing="ex"></aop:after-throwing>-->
            </aop:aspect>
        </aop:config>

<aop:aspect是新的标签,在这个标签下面就可以进行写了

Acspectj和SchemaBased的异同

1. 相同点:

在不修改源码的情况下都能实现功能的扩展。

2. 不同点:

(1) SchemaBased方式基于接口来区别前置和后置和环绕和异常通知的,而AspectJ方式是在配置文件中使用标签来区分。

(2) AspectJ方式在配置中的配置方式发现其切点的声明以及对应的通知组装中,切点只在Aop:aspect标签下有效。而SchemaBased方式声明的切点在全局有效.SchemaBased的切点的通用性比AspectJ方式要好。

SpringAOP的切点的声明格式

① 切点是某包某类的无参数的方法: 示例:

代码语言:javascript
复制
execution(* com.bjsxt.service.impl.Student.test())

② 切点是某包某类带有参数的方法 示例:

代码语言:javascript
复制
execution(*                 com.bjsxt.service.impl.Student.test(String,int))

③ 切点是某包某类的某个同名的所有方法 示例:… 表示任意个数任意类型的参数

代码语言:javascript
复制
execution(* com.service.impl.Student.test(..))

④ 切点是某包下的某类的所有方法 示例:*表示任意的类名,方法名,包名

代码语言:javascript
复制
execution(* com.service.impl.Student.*(..))

⑤ 切点是某包下的所有类的所有方法 示例:* 表示任意的类名,方法名,包名

代码语言:javascript
复制
execution(* com.service.impl.*.*(..))

注解

注意:

SpringAOP的注解方式实现是基于AspectJ方式的。

SchemaBased方式是没有的。

使用:

① 必须在applicationcontext.xml文件中声明注解的使用路径,方便Spring容器对象的扫描,提升扫描效率。

代码语言:javascript
复制
<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.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd




之后写这两句话
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd
        ">
  



  <!--配置注解扫描路径-->context:component-scan这个标签的使用需要前面的导入
base-package属性是  哪一个包下面的文件需要走注解   多个包用逗号隔开
        <context:component-scan base-package="com.advice,com.pojo"></context:component-scan>
 


<!--配置AOP注解生效-->

        <aop:aspectj-autoproxy expose-proxy="true"></aop:aspectj-autoproxy>

① @Component

作用:

相当于配置文件的bean标签,将某个类的对象扫描到Spring容器中。此注解一般在普通Java类上用。

注意:

默认类名的首字母小写即为bean对象的ID,也可以使用注解

的value属性声明自定义的ID,value可以省略不写。

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

使用:

声明在类上。

② @Service

作用:

相当于配置文件的bean标签,将某个类的对象扫描到Spring容器 中。此注解专门在业务层实体类上使用来表明该类为业务类

注意:

默认类名的首字母小写即为bean对象的ID,也可以使用注解的 value属性声明自定义的ID,value可以省略不写。

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

③ @pointcut

作用:声明切点

使用:在切点方法上使用

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

④ @Aspect

作用:声明该类为通知类

使用:结合@Component在通知类上使用

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

⑤ @Before

作用:声明方法为前置通知方法

使用:在前置通知方法上声明

注意:需要在其中声明对应的切点的全限定路径

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

⑥ @After

作用:声明方法为后置通知方法

使用:在后置通知方法上声明

注意:需要在其中声明对应的切点的全限定路径

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

⑦ @Around

作用:声明方法为环绕通知方法

使用:在环绕通知方法上声明

注意:需要在其中声明对应的切点的全限定路径

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

⑧ @AfterThrowing

作用:声明方法为异常通知方法

使用:在异常通知方法上声明

注意:需要在其中声明对应的切点的全限定路径

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

注意:

需要在Spring的配置文件中声明AOP注解生效

在这里插入图片描述
在这里插入图片描述
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021/07/01 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 目录
  • SpringAOP的Aspectj方式实现
    • 前提
      • 之前的方式有问题:
        • 解决:
          • 实现:
            • 使用
            • Acspectj和SchemaBased的异同
              • 1. 相同点:
                • 2. 不同点:
                • SpringAOP的切点的声明格式
                • 注解
                  • ① @Component
                    • ② @Service
                      • ③ @pointcut
                        • ④ @Aspect
                          • ⑤ @Before
                            • ⑥ @After
                              • ⑦ @Around
                                • ⑧ @AfterThrowing
                                相关产品与服务
                                容器服务
                                腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
                                领券
                                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档