Spring笔记(2)

Spring笔记(2)

一、AOP简介

1.概念:

  • 面向切面编程(Aspect-Oriented Programming),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。

  • AOP实际是GoF设计模式的延续,设计模式孜孜不倦追求的是调用者和被调用者之间的解耦,提高代码的灵活性和可扩展性,AOP可以说也是这种目标的一种实现。

2.作用

在程序运行期间,在不修改源码的情况下对方法进行功能的增强

  • 日志记录,性能统计,安全控制,事务处理,异常处理等等wn及扩展

3.底层实现

AOP的动态代理技术

JDK代理

基于接口的动态代理技术

image-20210318161029482

cglib代理

基于父类动态代理技术

image-20210318161056876

4.知识要点

aop:面向切面编程

aop底层实现:基于jdk的动态代理和基于cglib的动态代理

aop的重点概念:

  • ​ Pointcut(切入点):被增强的方法
  • ​ Adivce(通知/增强):封装增强业务逻辑的方法
  • ​ Aspect(切面):切点+通知
  • ​ Weaving(织入):将切点与通知结合的过程

二、基于XML的AOP开发

1.快速入门

步骤

  1. 添加坐标,spring-context 和 aop

    <!--    spring-context-->
        <dependency>
          <groupId>org.springframework</groupId>
          <artifactId>spring-context</artifactId>
          <version>5.0.5.RELEASE</version>
        </dependency>
    <!--    aop-->
        <dependency>
          <groupId>org.aspectj</groupId>
          <artifactId>aspectjweaver</artifactId>
          <version>1.8.13</version>
        </dependency>
      </dependencies>
    
  2. 创建目标接口并实现目标接口(连接点,切入点)

    //接口类
    public interface TargetInterface {
        public void save();
    }
    
    //实现类
     @Override
        public void save() {
            System.out.println("saving..");
        }
    
  3. 创建切面类(内写增强方法)

    //切面类
    public class MyAspect {
        public void before(){
            System.out.println("前置增强。。。");
        }
    }
    
  4. 创建applicationContext.xml文件,并将目标对象切面类注入

    <!--    目标对象-->
        <bean id="target" class="AopLearn.Target"></bean>
    
    
    <!--    切面对象-->
        <bean id="myAspect" class="AopLearn.MyAspect"></bean>
    
  5. 引入aop命名空间

    xmlns:aop="http://www.springframework.org/schema/aop"
    http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
    
  6. 配置织入,告诉spring框架,哪些方法(切点)需要进行那些增强(前置、后置)

        <aop:config>
    <!--        声明切面-->
            <aop:aspect ref="myAspect">
    <!--            声明切点和通知-->
                <aop:before method="before" pointcut="execution(public void AopLearn.Target.save())">
            </aop:aspect>
        </aop:config>
    

2.切点表达式

表达式语法:

​ execution([修饰符] 返回值类型 包名.类名.方法名(参数))

注:

  • 返回值类型、包名、类名、方法名可以使用星号*代表任意
  • 访问修饰符可以省略
  • 包名与类名之间一个点.代表当前包下的类,两个点表示当前包及其子包下的类
  • 参数列表可以使用两个点…示任意个数,任意类型的参数列表

常用:

excution( com itheima.app. .* (..));**

​ 任意返回值 it黑马aop包下的 任意类的 任意方法

抽取(易于维护 ):

<!--            抽取切点表达式-->
            <aop:pointcut id="myPointcut" expression="execution(* AopLearn.*.*(..))"/>
<!--            使用抽取的切点表达式-->
            <aop:before method="before" pointcut-ref="myPointcut"/>

3.通知的类型

  • 前置通知:调用目标组件前,调用方面组件(before)

  • <aop:before method="before" pointcut="execution(public void AopLearn.Target.save())"></aop:before>
    
  • 后置通知:调用目标组件后,调用方面组件(after-returning)

  • 最终通知:调用目标组件后,在finally里调用方面组件(after)

  • 异常通知:目标组件发生异常时,调用方面组件。(after-throwing)

  • 环绕通知:调用目标组件前、后,分别调用一次方面组件。(around)

三、基于注解的AOP开发

1.快速入门

  1. 创建目标接口目标类

  2. 创建切面类

  3. 将目标类和切面类的创建权交给Spring管理,并设置切面类标识。 (生成bean

    
    //实现bean的注入
    @Component("target")
    public class Target implements TargetInterface {
        @Override
        public void save() {
            System.out.println("saving..");
        }
    }
    
    //实现bean的注入
    @Component("myAspect")
    //配置为切面类
    @Aspect
    public class MyAspect {
        //注解配置织入关系
        @Before("execution(* Annotation.*.*(..))")
        public void before(){
            System.out.println("anno前置增强。。。");
        }
    }
    
  4. 在切面类中使用注解配置织入关系

    public class MyAspect {
        //注解配置织入关系
        @Before("execution(* Annotation.*.*(..))")
        public void before(){
            System.out.println("anno前置增强。。。");
        }
    }
    
  5. 创建context命名空间

  6. 在配置文件中开启组件扫描AOP的自动代理

    <!--        开启组件扫描-->
            <context:component-scan base-package="Annotation"/>
    <!--    aop自动代理-->
            <aop:aspectj-autoproxy/>
    
  7. 测试

    @Test
    public void test02(){
        ApplicationContext app = new ClassPathXmlApplicationContext("applicationContext-anno.xml");
        TargetInterface target = app.getBean(TargetInterface.class);
        target.save();
    }
    

2.切点表达式

抽取

/**
 * 定义切点表达式
 */
@Pointcut("execution(* Annotation.*.*(..))")
public void pointcut(){}

配置织入关系

@Before("pointcut()")
public void before(){
    System.out.println("anno前置增强。。。");
}

3.通知的类型

  • @Before — 前置通知

  • @AfterReturning — 后置通知

  • @Around — 环绕通知(目标对象默认不执行,需要手动执行)

  • @After — 最终通知

  • @AfterThrowing — 异常抛出通知

4.注意

使用@Aspect标注切面类

一定配置aop自动代理

<!--    aop自动代理-->
        <aop:aspectj-autoproxy/>
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/115201.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • 深度学习笔记(三):激活函数和损失函数

    深度学习笔记(三):激活函数和损失函数这一部分来探讨下激活函数和损失函数。在之前的logistic和神经网络中,激活函数是sigmoid,损失函数是平方函数。但是这并不是固定的。事实上,这两部分都有很多其他不错的选项,下面来一一讨论3.激活函数和损失函数3.1激活函数关于激活函数,首先要搞清楚的问题是,激活函数是什么,有什么用?不用激活函数可不可以?答案是不可以。激活函数的主要作用是提供网络的非线性建模能力。如果没有激活函数,那么

  • iframe自适应高度_html页面自适应

    iframe自适应高度_html页面自适应为什么需要使用iframe自适应高度呢?其实就是为了美观,要不然iframe和窗口长短大小不一,看起来总是不那么舒服,特别是对于我们这些编程的来说,如鲠在喉的感觉。在页面中通过iframe嵌入了另外一个页面后,如何使得页面的这块区域随着iframe的高度自动适应而不会出现蹩脚的上下左右滚动条呢?下面这个办法就是使用javascript实现iframe高度自适应的,这个可是兼容所有浏览器的,ie,f…

    2022年10月12日
  • The Feynman Technique The Best Way to Learn Anything理查德•弗曼学习法「建议收藏」

    The Feynman Technique The Best Way to Learn Anything理查德•弗曼学习法「建议收藏」https://fs.blog/2012/04/feynman-technique/TheFeynmanTechnique:TheBestWaytoLearnAnythingREADINGTIME:3MINUTESIfyou’reafterawaytosuperchargeyourlearningandbecomesmarter,TheFeynmanTechniquemightjustbethebestwaytolearnabsolu

  • 怎样修改hosts文件权限_修改host显示没有权限怎么办

    怎样修改hosts文件权限_修改host显示没有权限怎么办文章目录1.打开host文件2.右键属性->安全->高级3.更改->高级->立即查找4.在下拉菜单中找到”本地账户”确定->确定->应用5.出现弹窗->确定->确定6.编辑->选中组或用户名当中的”Users(DESKTOP-XXXXX\users)”->勾选Users的权限下的:允许完全控制->点应用->确定即可修改hosts文件了。1.打开host文件文件位置C:\Windows\System32\drivers\etc

    2022年10月12日
  • Ajax发送请求的四个步骤

    Ajax发送请求的四个步骤<scripttype=”text/javascript”> window.onload=function(){ varbtn=document.getElementById(‘btn’); btn.onclick=function(){ //使用Ajax发送请求需要如下几步 //1、创建XMLHttpRequest(); varxhr=…

  • Nginx的默认端口是_https默认端口

    Nginx的默认端口是_https默认端口我们前面一篇说了nginx的默认端口是80,可是空说无凭,我们用事实来说话。我们首先用whereisnginx.conf来看一下哪些目录里面有nginx.conf文件,我们看到了一共有6个目录,这里是应该分别到这六个文件里面去看一下,但是由于我们提前找过了,是/etc/nginx这个目录,所以我们就直接到该目录下面,即采用cd来切换目录,下图已经把这个文件标出来了。接着,我们查看…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号