Java设计模式和AOP编程
Java 六大设计原则;Java 23种设计模式(在此介绍三种设计模式)
Java设计模式
单例模式
应用场景:spring中bean的作用域用的就是单例模式
//基本的单例模式————懒汉式
public class student {//3.创建static修饰的成员变量private static student stu;//1.设计私有构造方法private student() {}//2.提供一个共有的方法public static synchronized student getInstance(){if (stu == null){stu = new student();}return stu;}
}//基本的单例模式————饿汉式public class student {//3.创建static修饰的成员变量private static student stu = new student();//1.设计私有构造方法private student() {}//2.提供一个共有的方法public static synchronized student getInstance(){return stu;}}/*饿汉式与懒汉式的不同是:创建对象的时间点不同*///测试类student stu1 = student.getInstance();student stu2 = student.getInstance();System.out.println(stu1 == stu2);
工厂模式
//工厂类
public class NoodleFactory {//定义静态常量的标识————规定下面条的类型public static final int NOODLE_BIA = 1;public static final int NOODLE_REGAN = 2;public static final int NOODLE_LANZHOU = 3;//创建不同类型的面条public static INoodles getNoodle(int type) {if (type == 1) {return new BiaBiaMianImp();}else if(type == 2){return new ReGanMianImp();}else if(type == 3){return new LanzhouLaMianImp();}return null;}
}//测试类
public class Test01 {public static void main(String[] args) {//方式1NoodleFactory.getNoodle(2).noodleType();//方式2NoodleFactory.getNoodle(NoodleFactory.NOODLE_REGAN).noodleType();}
}//自定义接口及实现类
public interface INoodles {public void noodleType();
}public class BiaBiaMianImp implements INoodles{@Overridepublic void noodleType() {System.out.println("----来一碗边个边个面---");}
}public class LanzhouLaMianImp implements INoodles{@Overridepublic void noodleType() {System.out.println("-----来一碗兰州拉面----");}
}public class ReGanMianImp implements INoodles{@Overridepublic void noodleType() {System.out.println("----来一碗武汉热干面----");}
}
代理模式
功能:中间隔离;方法增强
静态代理
- 是由程序员创建或特定工具自动生成源代码,在对其编译。
- 在程序员运行之前,代理类.class文件就已经被创建了。
//自定义接口
public interface IWomen {public void makeEyeWithMan();
}//被代理对象
public class PanJinLianImp implements IWomen{@Overridepublic void makeEyeWithMan() {System.out.println("给ximenqing抛媚眼");}
}//代理
public class WangPoImp implements IWomen{//被代理对象IWomen obj;//构造方法给属性赋值public WangPoImp(IWomen obj) {this.obj = obj;}@Overridepublic void makeEyeWithMan() {System.out.println("镇壶酒,搞点气氛");obj.makeEyeWithMan();}
}//测试类
public class XiMenTest {public static void main(String[] args) {//1.创建被代理对象IWomen pan = new PanJinLianImp();//2.创建代理IWomen wang = new WangPoImp(pan);wang.makeEyeWithMan();}
}
动态代理
- 在程序运行时通过反射机制动态创建的。
- 动态代理分为: 基于接口的动态代理(jdk自带);基于子类的动态代理(第三方)
基于接口的动态代理(jdk自带)
//自定义接口
public interface ISinger {public void sing();public int dance(int num);
}//被代理
public class JinXingImp implements ISinger{@Overridepublic void sing() {System.out.println("----有点甜---");}@Overridepublic int dance(int num) {System.out.println("---哈哈哈哈----");return 0;}
}//jdk动态代理测试
public class Test01 {public static void main(String[] args) {//1.创建被代理对象final ISinger jin = new JinXingImp();//2.创建代理对象final ISinger daiLi = (ISinger) Proxy.newProxyInstance(jin.getClass().getClassLoader(), jin.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("------自我介绍-----");Object obj = method.invoke(jin, args);return obj;}});daiLi.sing();daiLi.dance(6);}
}
基于子类的动态代理(第三方)
//自定义接口
public interface ISinger {public void sing();public int dance(int num);}//实现接口的类
public class TengImp implements ISinger{@Overridepublic void sing() {System.out.println("听了赵雷的成都去了成都,听了汪峰的北京去了北京,至今不敢听腾格尔的天堂");}@Overridepublic int dance(int num) {System.out.println("学武术,跳舞");return 0;}
}//cglib动态代理测试
public class Test02 {public static void main(String[] args) {//1.创建被代理对象final ISinger teng = new TengImp();//2.创建代理对象ISinger dai = (ISinger) Enhancer.create(teng.getClass(), teng.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {Object obj = method.invoke(teng,objects);return obj;}});dai.sing();dai.dance(6);}
}
用动态代理的优化转账业务的案例见资源
AOP(面向切面编程)
AOP概述
将那些与业务无关,却为业务模块所共同调用的逻辑(例如:事务管理、日志管理、控制权限等)封装抽取成一个可重用的模块,这个模块被命名为"切面(Aspect)",便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性
Spring AOP 基于动态代理实现
- 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象(JDK动态代理的核心是InvocationHandler接口和Proxy类);
- 如果被代理的对象,没有实现某个接口,就无法使用 JDK Proxy 去进行代理了,这时候 Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理(Cglib动态代理的核心是MethodInterceptor接口和Enhancer类)
AOP相关概念
AOP通知类型
AOP将抽取出来的共性功能称为通知;通知类型:以通知在上下文中的具体位置作为划分
前置通知(Before)
返回通知(After-returning)
异常通知(After-throwing)
后置通知(After)
环绕通知(Around)
AOP连接点(Join point)
AOP将所有的方法都视为连接点,不管是接口里面的抽象方法,还是实现类里面的重写方法,都是连接点
AOP切点(Pointcut)
AOP将可能被抽取共性功能的方法称为切入点。切入点是连接点的子集
AOP目标对象(Target)
就是挖掉功能的方法对应的类生的对象,这种对象是无法直接完成最终工作的
AOP织入(Weaving)
是将挖掉的功能回填的动态过程
AOP切面
切点+通知
SpringAOP+AspectJ实现步骤
1.添加依赖,aop与aspectj表达式的依赖
2.创建spring的主配置文件,bean内的命名空间要添加aop的
3.创建业务代码并编写日志记录代码(事务管理代码)
4.将业务层与日志记录层注入spring容器
5.<aop:config>--aop配置 aop:aspect--aop切面 aop:before--通知内容与通知类型
切点表达式配置语法
execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
eg: execution(public void com.apesource.service.ServiceImp.findAll())
- 1.修饰符可以省略代表任意 execution(返回值 包名称.类名称.方法名称(参数列表))
- 2.返回值可以使用“*”代表任意 execution(* 包名称.类名称.方法名称(参数列表))
- 3.包名可以使用“*”代表任意名称 execution(* *.*.*.类名称.方法名称(参数列表))
- 4.包名可以使用“..”代表任意个数 execution(* *...类名称.方法名称(参数列表))
- 5.类名与方法名可以使用“*”代表任意 execution(* *...*.*(参数列表))
- 6.参数列表可以使用".."代表任意个数任意类型 execution(* *...*.*(..))
注:如果有参数 int======>int; String===>java.lang.String
xml版的面向切面编程案例部分代码展示
//日志工具类
public class Logger {public void brforeLogger(){System.out.println("日志类logger中调用前置Logger方法进行日志记录");}public void returnLogger(){System.out.println("日志类logger中调用返回Logger方法进行日志记录");}public void throwLogger(){System.out.println("日志类logger中调用异常Logger方法进行日志记录");}public void afterLogger(){System.out.println("日志类logger中调用后置Logger方法进行日志记录");}//环绕通知public Object arroundMethod(ProceedingJoinPoint pjp){Object obj=null;try{System.out.println("环绕---------前置通知");//切点方法Object[] args = pjp.getArgs(); //参数obj = pjp.proceed(args); //调用切点的所有方法System.out.println("环绕---------返回通知");}catch (Throwable e){System.out.println("环绕---------异常通知");}finally {System.out.println("环绕---------后置通知");return obj;}}
}//applicationContext.xml
<!--注入业务层--><bean id="accountServiceImp" class="com.apesource.service.AccountServiceImp"></bean><!--注入日志记录层--><bean id="logger" class="com.apesource.util.Logger"></bean><!--配置AOP--><aop:config><!--配置切面--><aop:aspect id="aopAspect" ref="logger"><!--配置通知类型,并建立通知方法和切入点方法的关联--><!--切点 expression = execution(修饰符{可省略} 返回值 包名称.类名称.方法名称(参数列表))--><aop:pointcut id="dian" expression="execution(* com.apesource.service.*.*(..))"/><!--通知-->
<!-- <aop:before method="brforeLogger" pointcut-ref="dian"></aop:before>-->
<!-- <aop:after-returning method="returnLogger" pointcut-ref="dian"/>-->
<!-- <aop:after-throwing method="throwLogger" pointcut-ref="dian"/>-->
<!-- <aop:after method="afterLogger" pointcut-ref="dian"/>--><aop:around method="arroundMethod" pointcut-ref="dian"/></aop:aspect></aop:config>//测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class Test01 {@Autowiredpublic IAccountService service;@Testpublic void show1(){service.update();System.out.println("----------");service.save(1);System.out.println("-----------");service.delete();}
}
注解版的面向切面编程案例部分代码展示
//logger日志
@Component
@Aspect //切面
public class Logger {@Pointcut("execution(* com.apesource.service.*.*(..))")public void dian(){}@Before("dian()")public void beforeLogger(){System.out.println("日志类logger中调用前置Logger方法进行日志记录");}@AfterReturning("dian()")public void returnLogger(){System.out.println("日志类logger中调用返回Logger方法进行日志记录");}@AfterThrowing("dian()")public void throwLogger(){System.out.println("日志类logger中调用异常Logger方法进行日志记录");}@After("dian()")public void afterLogger(){System.out.println("日志类logger中调用后置Logger方法进行日志记录");}//环绕通知
// @Around("dian()")public Object arroundMethod(ProceedingJoinPoint pjp){Object obj=null; //保存主业务犯法的返回值try{System.out.println("环绕---------前置通知");//切点方法Object[] args = pjp.getArgs(); //参数obj = pjp.proceed(args); //调用切点的所有方法System.out.println("环绕---------返回通知");}catch (Throwable e){System.out.println("环绕---------异常通知");}finally {System.out.println("环绕---------后置通知");return obj;}}
}//applicationContext.xml<!--扫描--><context:component-scan base-package="com.apesource"></context:component-scan><!--开启spring注解的aop动态代理--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>相关文章:
Java设计模式和AOP编程
Java 六大设计原则;Java 23种设计模式(在此介绍三种设计模式) Java设计模式 单例模式 应用场景:spring中bean的作用域用的就是单例模式 //基本的单例模式————懒汉式 public class student {//3.创建static修饰的成员变量p…...
【扒代码】data.py
数据增强函数 import torch from torchvision.transforms import functional as TVFdef tiling_augmentation(img, bboxes, density_map, resize, jitter, tile_size, hflip_p):# 定义一个辅助函数,用于根据给定的概率水平翻转张量def apply_hflip(tensor, apply)…...
【时时三省】unity test 测试框架 介绍(适用于C语言进行测试的)
山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 目录 1,关于 unity test 测试框架的介绍 2,测试框架关于源码的介绍 3,使用unity test测试C代码 4,常用断言举例 1,关于 unity test 测试框架的介绍 unity test 是 ThrowTheSwitch.org 的一个主要工程。它…...
那些你应该掌握的linux命令
一、路径授权 要给 a 用户 b 路径的所有操作权限,可以使用以下命令: sudo chown -R a:a /b sudo chmod -R 770 /b1.sudo chown -R a:a /b chown 命令用于更改文件或目录的所有者和所属组。-R 选项表示递归地应用于目录及其内部的所有文件和子目录。a:a 表示将所有…...
系统出现高CPU可能风险因素整理
文章目录 死循环无限递归序列化加解密正则表达式计算密集型任务大流量Full GC资源竞争/死锁I/O阻塞外部接口调用 死循环 死循环是最常见的原因之一。当代码中存在无穷循环(例如在多线程环境下的HashMap线程不安全问题或分页查询条件不明确导致的无限循环࿰…...
前端技术 -- 动画效果之GSAP作用与使用示例
GSAP(GreenSock Animation Platform)简介 GSAP 是一个高性能、跨平台的 JavaScript 动画库,广泛用于网页动画的制作。它提供了丰富的 API,使得开发者可以轻松创建复杂的动画效果,并且在不同浏览器和设备上都能获得一致…...
C口一拖二数据线:解锁数字生活的便捷新篇章LDR6020
添加图片注释,不超过 140 字(可选) 在科技日新月异的今天,我们的电子设备如同生活中的伴侣,无论是工作、学习还是娱乐,都离不开它们的陪伴。随着Type-C接口逐渐成为众多高端智能手机、平板电脑、笔记本电脑…...
CH07_数据绑定
第7章:数据绑定 本章目标 理解路由事件 掌握键盘输入事件 掌握鼠标输入事件 掌握多点触控输入事件 数据绑定概述 什么是数据绑定 将WPF中的至少一个带有依赖项属性的两个对象的两个属性进行绑定,使某一个依赖项属性可以更新和它绑定的属性的功…...
24.python基础(8.8)
python基础 1.搭建环境python3 1.查看是否有安装python [rootpython1 ~]# yum list installed |grep python 2.安装python3 [rootpython1 ~]#yum -y install python3 [rootpython1 ~]#python --version #查看版本信息 最新安装3.12,可以使用源码安装 开…...
【论文阅读】MobileNetV4 - Universal Models for the Mobile Ecosystem
文章目录 摘要一、介绍二、相关工作三、与硬件无关的帕累托效率四、通用倒置瓶颈五、移动MQA六、MNv4模型的设计6.1 为增强的体系结构改进NAS6.2 MNv4模型的优化 7. 结果7.1 ImageNet分类7.2 COCO目标检测 8. 强化蒸馏配方9. 结论 MobileNetV4 - 移动生态系统的通用模型 摘要 …...
大模型日报 2024-08-07
大模型日报 2024-08-07 大模型资讯 [Figure AI 把「终结者」造出来了] 简介:Figure 发布新一代人形机器人 Figure 02,具多种功能,能实时对话、自主执行任务,导航用 VLM,电池续航提升,机械手先进,…...
区块链ddos防护怎么做
区块链ddos防护怎么做?在区块链这一新兴技术的浪潮中,我们见证了无数创新应用的诞生与繁荣。然而,在这片充满机遇的蓝海中,也潜藏着不容忽视的暗流——分布式拒绝服务攻击(DDoS)。DDoS攻击,如同网络世界的…...
在Linux中认识pthread库
int *pnullptr; pnullptr; *pnullptr; 指针变量做右值也是变量拥有空间。去承装数据。 *p代表指针所指向的空间,及0号地址,及往虚拟地址的0号地址处写8个字节的数据,全部写为0. (此操作不允许) 进程和线程的关系如…...
LVS 负载均衡
目录 LVS 体系结构 LVS 相关概念术语 lvs 集群常见类型 实验一: LVS NAT模式 LVS NAT特性 实验二: LVS DR模式 LVS DR特性 LVS是Linux virtual server的缩写,是一个高性能的、开源的负载均衡器,它运行于Linux操作系统之上…...
在Excel中启用宏 (~ ̄▽ ̄)~
一、启用宏 打开任意Excel,点击屏幕左上角的文件选项,然后选择Excel选项窗口。在Excel选项窗口中,选择信任中心按钮;在信任中心设置窗口中,选择宏设置,启用所有宏(不推荐,潜在风险&a…...
连接投影仪/显示器只能扩展不能复制的解决方案
原文章:https://iknow.lenovo.com.cn/detail/121481 故障现象: 笔记本外接投影仪/显示器后,笔记本屏幕有显示,但投影仪却只有背景或没有显示; 原因分析: 此现象多发生在双显卡机型上,笔记本屏…...
数据库基础知识
数据库基础知识 主流的数据库连接MySQL理解mysql和mysqld和数据库简单对数据库操作MySQL构架SQL分类存储引擎总结 主流的数据库 SQL Sever: 微软的产品,.Net程序员的最爱,中大型项目。Oracle: 甲骨文产品,适合大型项目…...
java JVM 锁消除
Java虚拟机 (JVM) 中的锁消除 (Lock Elimination) 是一种编译时优化技术,用于减少或完全去除不必要的同步操作。锁消除可以显著提高程序的性能,尤其是在多线程环境中。下面详细介绍锁消除的工作原理和技术细节。 锁消除的目的 锁消除的目标是在编译阶段…...
基于 Java Supplier与Predicate 封装自动重试机制通用接口
核心逻辑就是把重试的业务与重试中断条件抽象出来函数化,内部重试业务具体化。 关键需要理解Java的函数式接口编程 Supplier 与 Predicate作用。 import lombok.Data; import lombok.extern.slf4j.Slf4j;import java.util.Random; import java.util.function.Predi…...
Java面试题(基础篇)②
目录 一,float f3.4 是否正确? 二,重写和重载的区别是什么 三,this和super的应用场景是什么 四,throw和throws的区别是什么 五,应该使用什么数据类型来计算价格 一,float f3.4 是否正确&am…...
HTML 语义化
目录 HTML 语义化HTML5 新特性HTML 语义化的好处语义化标签的使用场景最佳实践 HTML 语义化 HTML5 新特性 标准答案: 语义化标签: <header>:页头<nav>:导航<main>:主要内容<article>&#x…...
中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...
java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别
UnsatisfiedLinkError 在对接硬件设备中,我们会遇到使用 java 调用 dll文件 的情况,此时大概率出现UnsatisfiedLinkError链接错误,原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用,结果 dll 未实现 JNI 协…...
django filter 统计数量 按属性去重
在Django中,如果你想要根据某个属性对查询集进行去重并统计数量,你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求: 方法1:使用annotate()和Count 假设你有一个模型Item,并且你想…...
测试markdown--肇兴
day1: 1、去程:7:04 --11:32高铁 高铁右转上售票大厅2楼,穿过候车厅下一楼,上大巴车 ¥10/人 **2、到达:**12点多到达寨子,买门票,美团/抖音:¥78人 3、中饭&a…...
剑指offer20_链表中环的入口节点
链表中环的入口节点 给定一个链表,若其中包含环,则输出环的入口节点。 若其中不包含环,则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...
【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
AI病理诊断七剑下天山,医疗未来触手可及
一、病理诊断困局:刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断",医生需通过显微镜观察组织切片,在细胞迷宫中捕捉癌变信号。某省病理质控报告显示,基层医院误诊率达12%-15%,专家会诊…...
vulnyx Blogger writeup
信息收集 arp-scan nmap 获取userFlag 上web看看 一个默认的页面,gobuster扫一下目录 可以看到扫出的目录中得到了一个有价值的目录/wordpress,说明目标所使用的cms是wordpress,访问http://192.168.43.213/wordpress/然后查看源码能看到 这…...
