分布式补充技术 01.AOP技术

01.AOP技术是对于面向对象编程(OOP)的补充。是按照OCP原则进行的编写,(ocp是修改模块权限不行,扩充可以)
02.写一个例子:
创建一个新的java项目,在main主启动类中,写如下代码。

package com.company;

interface mainService{
    void send();
}
class DefaultServiceImpl implements mainService
{
    @Override
    public void send() {
        System.out.println("hello");
    }
}
public class main {
    public static void main(String[] args){
         DefaultServiceImpl defaultService=new DefaultServiceImpl();
         defaultService.send();
    }
}

一个接口,一个接口实现类,一个main主方法。

03.如果要实现显示接口实现类中的send方法运行的时间,一般的就在实现类中的send方法前后添加system.currenttimeMills

 @Override
    public void send() {
        System.out.println("start:"+System.currentTimeMillis());
        System.out.println("hello");
        System.out.println("end:"+System.currentTimeMillis());
    }

04.如果在项目的发布后,或者以后接口实现类以后代码多,如何去修改项目呢?实现显示运行时间呢?
方法一:继续写一个子类去继承接口实现类。

class DefaultServiceImpl implements mainService
{
    @Override
    public void send() {
       // System.out.println("start:"+System.currentTimeMillis());
        System.out.println("hello");
      //  System.out.println("end:"+System.currentTimeMillis());
    }
}

class logDefaultImpl extends DefaultServiceImpl
{
    @Override
    public void send() {
        System.out.println("start:"+System.currentTimeMillis());
        System.out.println("hello");
        System.out.println("end:"+System.currentTimeMillis());
    }
}
package com.company;

interface mainService{
    void send();
}
class DefaultServiceImpl implements mainService
{
    @Override
    public void send() {
       // System.out.println("start:"+System.currentTimeMillis());
        System.out.println("hello");
      //  System.out.println("end:"+System.currentTimeMillis());
    }
}

class logDefaultImpl extends DefaultServiceImpl
{
    @Override
    public void send() {
        System.out.println("start:"+System.currentTimeMillis());
        System.out.println("hello");
        System.out.println("end:"+System.currentTimeMillis());
    }
}
public class main {
    public static void main(String[] args){
         mainService logDefaultImpl=new logDefaultImpl();
        logDefaultImpl.send();
    }
}

方法二:如果接口实现类被final修饰的话,不能用子类来继承,可以写一个集合来实现运行时间的功能

final class DefaultServiceImpl implements mainService
{
    @Override
    public void send() {
        System.out.println("hello");
    }
}

创建一个新的类,也同样实现接口mainService:
在这个类中声明一个接口的变量:

class logDefaultImpl implements mainService
{
    private mainService mainservice;
    public logDefaultImpl(mainService mainservice){
        this.mainservice=mainservice;
    }
    @Override
    public void send() {
        System.out.println("start:"+System.currentTimeMillis());
        mainservice.send();
        System.out.println("end:"+System.currentTimeMillis());
    }
}

在main主方法中:

public class main {
    public static void main(String[] args){
        mainService DefaultServiceImpl=new DefaultServiceImpl();
        DefaultServiceImpl.send();
        mainService log=new logDefaultImpl(new DefaultServiceImpl());
        log.send();
    }
}

通过构造函数,将final修饰的接口实现类传入到新的类中,结合方法,来实现显示运行时间的功能。

05.AOP技术的底层实现。
AOP对象是通过代理对象来实现的,代理对象有两种,一种是通过JDK来实现的,一种是通过CGlib来实现的。
在这里插入图片描述
jdk的代理就好像是使用一个新的类去继承接口,再来包含目标接口实现类
cglib是写一个子类去继承目标接口实现类。

06.AOP的术语
1切面:就是写了相关扩展功能的类
2.通知:就是切面中的相关方法
3.连接点:就是需要扩展的方法
4.切入点:就是连接点所在的类,有的时候也可能是一整个包。
在这里插入图片描述
07.在springboot中去实现AOP技术
先在maven项目中导入相关的依赖。
在这里插入图片描述

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>     
        </dependency>

在去写切面类,这里需要用注解@Aspect标识这个类是切面类,用@Component来将类交给spring容器进行管理。还需要使用到log4j来进行日志管理@Slf4j。

package com.cy.common;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Slf4j//日志
@Aspect//标识切面类
@Component//交给spring容器管理
public class sysLogAspect {
    @Pointcut("bean(sysUserServiceImpl)")
    //@Pointcut标识连接点(多个切入点的集合)
    public void logPointCut(){} 
    @Around("logPointCut()")//这个是环绕通知,属性是切入点
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
    //还是计算运行时间
    //并且执行方法
        Long startTime=System.currentTimeMillis();
        Object object= joinPoint.proceed();//调用本切面的其他方法或者其他切面的通知和目标
        Long endTime=System.currentTimeMillis();
        log.info("总时长是:",endTime-startTime);
        return object;
    }
    

}

@Pointcut标识连接点(多个切入点的集合),这里用来写的是连接点bean标识spring容器中的类,括号中的是类名,一般是接口的实现类impl。

这个切面的意义在于sysUserServiceImpl这个接口实现类的每一个方法都扩展了功能,记录运行时间。

07.在springboot项目导入AOP依赖后,项目实现路径发送了改变。
springboot版本2.x后,默认AOP代理是Cglib
运行:
在这里插入图片描述

AOP通知有五种:
在这里插入图片描述

package com.cy.common;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Slf4j
@Aspect
@Component
public class sysTimeAspect {
    @Pointcut("bean(sysUserServiceImpl)")
    public void doTime(){}
    @Around("doTime()")
    public Object aroud(ProceedingJoinPoint joinPoint) throws Throwable {
        Long startTime=System.currentTimeMillis();
        Object object= joinPoint.proceed();
        Long endTime=System.currentTimeMillis();
        log.info("总时长是:",endTime-startTime);
        System.out.println("通知around");
        return object;
    }
    //前置
    @Before("doTime()")
    public void before()  {
        System.out.println("通知before");
    }
    //后置
    @After("doTime()")
    public void after()  {
        System.out.println("通知before");
    }
    //正常
    @AfterReturning("doTime()")
    public void AfterReturn()  {
        System.out.println("通知AfterReturning");
    }
    //异常
    @AfterThrowing("doTime()")
    public void AfterThrow()  {
        System.out.println("通知AfterThrowing");
    }
}

使用通知@AfterThrowing,在切面中去写一个异常通知,就是目标接口类方法运行时候有异常,切面类处理。

@Slf4j
@Aspect
@Component
public class sysExceptionAspect {
    @AfterThrowing(pointcut = "bean(sysUserServiceImpl)",throwing = "e")//pointcut是连接点,throwing是抛出的异常
    public void doHandlerException(JoinPoint jp//这个是切入点,Throwable e){
      MethodSignature ms= (MethodSignature)jp.getSignature();
      log.error("{},exception msg is {}",ms.getName(),e.getMessage());
    }

}

getsignature返回的类型是signature。
在这里插入图片描述

如果想要所有的接口实现类的运行方法报错时候有这个切面的类的AfterThrowing来处理异常,可以在bean中去写bean(*ServiceImpl)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/22414.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于无人机辅助边缘计算系统的节能卸载策略

源自&#xff1a;《系统工程与电子技术》 作者&#xff1a;余雪勇 朱烨 邱礼翔 朱洪波 摘 要 针对复杂地形中地面基础设施无法有效提供可靠通信和密集算力的问题,首先提出一种基于无人机(unmanned aerial vehicle, UAV)托管计算资源的卸载方案。考虑用户终端的计算需…

西门子PLC如何实现1主多从网口无线通讯

常规来说&#xff0c;多台plc要实现以太网无线连接&#xff0c;首先要先确定以太网线必须正确连接&#xff0c;并建立物理连接。然后需要在PLC端设置好IP地址&#xff0c;以使不同PLC以相同协议可以实现通信交流。最后是建立PLC端数据采集及交换系统&#xff0c;要求在PLC端设置…

直播和短视频美颜sdk的开发流程、代码分析

目前&#xff0c;美颜技术是提高视频质量的重要手段之一&#xff0c;特别是短视频和直播两个行业。本文将介绍其开发流程和代码分析。 一、美颜SDK的开发流程 1.需求分析 首先我们需要明确的一点就是“需求”&#xff0c;例如&#xff1a;美颜效果、美颜程度、性能要求等。同…

【JavaScript】线程和进程,JavaScript线程,事件队列,事件循环 ,微任务、宏任务

❤️ Author&#xff1a; 老九 ☕️ 个人博客&#xff1a;老九的CSDN博客 &#x1f64f; 个人名言&#xff1a;不可控之事 乐观面对 &#x1f60d; 系列专栏&#xff1a; 文章目录 进程和线程JavaScript线程事件队列、事件循环微任务、宏任务面试题1面试题2 进程和线程 进程&a…

Netty核心技术二--BIO编程

1. I/O模型 I/O 模型简单的理解&#xff1a;就是用什么样的通道进行数据的发送和接收&#xff0c;很大程度上决定了程序通信的性能 Java共支持3种网络编程模型/IO模式&#xff1a;BIO、NIO、AIO Java BIO &#xff1a;同步并阻塞(传统阻塞型)&#xff0c;服务器实现模式为一个…

C++13-STL模板

C13-STL模板 在线练习&#xff1a; http://noi.openjudge.cn/ https://www.luogu.com.cn/ 大纲要求 【 3 】算法模板库中的函数&#xff1a;min、max、swap、sort 【 4 】栈 (stack)、队列 (queue)、链表 (list)、 向量&#xff08;vector&#xff09;等容器 1.函数模板 泛…

1.2 IAR 环境配置及编译

目录 一. 新建源码文件夹 二. 添加源文件到工程中 三. 编写一个简单的测试程序 四. 设置字体和行号 五. 工程配置 六. 编译链接工程 一. 新建源码文件夹 &#xff08;1&#xff09;在保存工作空间和工程的目录下&#xff0c;新建一个code文件夹&#xff0c;用于保存源码&…

突破极限:YOLO9000 论文解读 - 构建更好、更快、更强大的实时检测系统

YOLOv2 论文全篇完整翻译 摘要 我们介绍了YOLO9000&#xff0c;这是一种先进的、实时的目标检测系统&#xff0c;可以检测超过9000个物体类别。首先&#xff0c;我们对YOLO检测方法进行了各种改进&#xff0c;包括新颖的方法和借鉴自先前工作的方法。改进后的模型YOLOv2在标准…

实验四 车辆定位导航

有想自己动手的同学可在末尾看教程 【实验目的】 1、了解全球定位导航系统的定位原理和电子地图技术&#xff0c;掌握电子地图API使用方法。 2、了解导航数据报文数据格式&#xff0c;解析导航数据并在电子地图上进行导航应用。 【实验性质】 验证性实验。 【实验要求】 1、相…

自抗扰PID(梯形图源代码)

有关ADRC的详细算法和源代码,请参看专栏的系列文章,这里不再赘述,常用链接如下: ADRC自抗扰控制算法(含梯形图完整源代码和算法公式)_adrc算法_RXXW_Dor的博客-CSDN博客PLC的自抗扰控制(ADRC)算法_RXXW_Dor的博客-CSDN博客_adrc算法1、自抗扰控制算法,网上很多文章有所…

数据仓库漫谈-前世今生

数据仓库的内容非常多&#xff0c;每一个子模块拎出来都能讲很久。这里没法讲太多细节&#xff0c;大致思考了三个备选议题&#xff1a; 数据仓库的前世今生 数据仓库体系知识介绍 数仓开发者的路在何方&#xff1f; 既然是第一次分享&#xff0c;感觉还是跟大家普及下数仓的…

浏览器数据存储方式

浏览器数据存储方式 常用的前端数据存储方法笼统来说有 3 种&#xff1a; local/session storagecookiesindexeddb 3 种方法各有各的优点和使用范围。 local/session storage local/session storage 保存的格式都为键值对&#xff0c;并且用法都是差不多&#xff0c;如下&…

『树莓派云台机器人』02. 电脑连接树莓派 配置开发环境

目录 1. 下载ssh交互工具 Xshell 与XFTP&#xff08;有过相关使用经历的朋友可以跳过这一节内容&#xff09;2. 下载VNC远程控制工具软件3. 连接过程4. Xshell 命令工具5. XFTP 文件传送工具6. 关于联网总结 欢迎关注 『树莓派云台机器人』 博客&#xff0c;持续更新中 欢迎关注…

基于Zynq的雷达10Gbps高速PCIE数据采集卡方案(三)软件设计

4.1 引言 本章基于第二章的分析结论&#xff0c;进行系统软件设计。软件设计包括逻辑设计、嵌入 式软件设计和上位机软件设计。在逻辑设计中&#xff0c;对 ADC 模块、 Aurora 模块、 DDR3 SDRAM 模块和 PCIE 模块进行分析和设计&#xff0c;在 Vivado 软件提供的 …

在 Linux 上使用 yuzu 模拟 Nintendo Switch 试玩王国之泪

王国之泪5月12日发售&#xff0c;DLC 玩家已经造出各种脑洞大开的东西了&#xff0c;但是买的卡带迟迟没有收到&#xff0c;因此&#xff0c;打算使用 yuzu 模拟器先体验一下 yuzu 是一款开源的 Ninetendo Switch 模拟器&#xff0c;支持在 Linux 或者 Windows 平台运行&#…

vue动态class的写法

本文会详细介绍 vue动态 class的写法&#xff0c;并且提供一些我个人的理解&#xff0c;希望对你有所帮助。 如果你是一个新手&#xff0c;或者想了解 vue的源码&#xff0c;那么首先应该学习 vue的基础知识&#xff0c;比如&#xff1a;什么是静态语言&#xff0c;有什么作用等…

JQuery原理剖析——自己手写简易版JQuery

知其一后知其二&#xff1b; 目录 为什么需要JQuery jQuery的概念&#xff1a; 在此之前回顾JavaScript对象知识&#xff1a; 自己手写的简易JQuery&#xff1a; 为什么需要JQuery 在我们之前写的JS代码中经常会遇见document.getElementById等等获取元素的对象&#xff0c…

Apache Kafka - 重识Kafka生产者

文章目录 概述Kafka 生产者Kafka 生产者工作原理如何使用 Kafka 生产者 生产者配置项&#xff08;核心&#xff09;导图总结 概述 Kafka 生产者是 Apache Kafka 中的一个重要组件&#xff0c;它负责将数据发送到 Kafka 集群中。在实时数据处理和流式处理应用程序中&#xff0c…

OKR是什么意思啊

一、OKR是什么意思&#xff1f; OKR是"Objective and Key Results"的缩写&#xff0c;即目标和关键结果。它是一种目标管理框架&#xff0c;旨在帮助组织和团队设定明确的目标&#xff0c;并通过关键结果来衡量和追踪目标的实现情况。 为了让大家快速了解什么是OKR…

Doxygen 源码分析: QCString类

2023-05-20 23:41:56 ChrisZZ imzhuofoxmailcom Hompage https://github.com/zchrissirhcz 文章目录 1. Doxygen 版本2. QCString 类概览3. QCString 特殊成员函数3.1 default 方式的构造函数3.2 单个参数和两个参数的构造函数 4. inline方式实现的成员函数4.1 operator 函数4.…