当前位置: 首页 > news >正文

定西市城乡建设局网站西安网站建设推广公司

定西市城乡建设局网站,西安网站建设推广公司,wordpress 数据库连接文件,wordpress鼠标特效目录 一、为什么需要代理#xff1f; 二、代理长什么样#xff1f; 三、Java通过什么来保证代理的样子#xff1f; 四、动态代理实现案例 五、动态代理在SpringBoot中的应用 导入依赖 数据库表设计 OperateLogEntity实体类 OperateLog枚举 RecordLog注解 上下文相…目录 一、为什么需要代理 二、代理长什么样 三、Java通过什么来保证代理的样子 四、动态代理实现案例 五、动态代理在SpringBoot中的应用 导入依赖 数据库表设计 OperateLogEntity实体类 OperateLog枚举 RecordLog注解 上下文相关类 OperateLogAspect切面类 OperateLogMapper 一、为什么需要代理 代理可以无侵入式地给对象增强其他的功能 例如以下方法 public static void playGame() {System.out.println(玩游戏); } 现在要对这个方法进行增强在玩游戏之前要先吃饭玩完游戏后要睡觉。 下面这种修改方法就是侵入式修改对原始的方法进行修改。缺点是会使代码变得繁琐扩展性变差。原本playGame()方法就是用来玩游戏的吃饭和睡觉不属于玩游戏的范畴。 public static void playGame() {System.out.println(吃饭);System.out.println(玩游戏);System.out.println(睡觉); } 为什么需要代理 代理就是调用playGame()方法并且在调用之前先吃饭玩完游戏后再睡觉。 类似于下面这种修改方式 public class Test {public static void main(String[] args) {action();}public static void action() {System.out.println(吃饭);playGame();System.out.println(睡觉);}public static void playGame() {System.out.println(玩游戏);} } 我们并没有直接调用playGame()方法而是通过action()方法间接调用playGame()方法。 所以代理的目的就是在调用方法时能在调用前或者调用后做一些事从而达到在不修改原始方法的基础上对原始方法进行增强。 当然我们要实现代理并不是用以上的方法上面的案例只是解释代理的作用是什么。 二、代理长什么样 代理里面就是对象要被代理的方法 简单理解代理就是一个对象这个对象里面有要被代理的方法。 被代理对象里面有playGame()方法代理对象里面也有playGame()方法并且是增强后的playGame()方法。 也就是说我们直接从代理对象里调用方法就行了代理就是一个对象。 那么如何获取代理对象呢 代理对象应该长得和被代理对象差不多才行所以我们可以根据被代理对象来创建代理对象。 三、Java通过什么来保证代理的样子 上面说到要根据被代理对象来创建代理对象既然两者是相似的可以想到如果代理对象和被代理对象继承了同一个父类两者不就相似了吗 因为代理对象和被代理对象虽然都有playGame()方法但是方法的实现不同只是方法的名称是一样的。 那么代理对象和被代理对象应该实现同一个接口接口中的方法也就是要被代理的方法。 四、动态代理实现案例 我们先定义一个OnePerson类其中playGame()方法就是要代理的方法所以我们再定义一个Person接口。Person接口里面写playGame()抽象方法代理对象也要实现Person接口并且重写playGame()方法。 public class OnePerson implements Person {private String name;private String gender;private Integer age;Overridepublic void playGame() {System.out.println(this.name 正在玩游戏);}public OnePerson() {}public OnePerson(String name, String gender, Integer age) {this.name name;this.gender gender;this.age age;}public String getName() {return name;}public void setName(String name) {this.name name;}public String getGender() {return gender;}public void setGender(String gender) {this.gender gender;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age age;}Overridepublic String toString() {return OnePerson{ name name \ , gender gender \ , age age };} } public interface Person {void playGame(); } ProxyUtils 定义生成代理对象的工具类 这里用到反射Method调用的方法就是原始的方法。 import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;public class ProxyUtils {public static Person createProxy(OnePerson onePerson) {return (Person) Proxy.newProxyInstance(ProxyUtils.class.getClassLoader(), // 类加载器new Class[]{Person.class}, // 接口指定要代理的方法new InvocationHandler() { // 调用并增强原始方法Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {String name onePerson.getName();if (method.getName().equals(playGame)) {System.out.println(name 在吃饭);}Object object method.invoke(onePerson, args);if (method.getName().equals(playGame)) {System.out.println(name 在睡觉);}return object;}});} } 案例测试 public class Test {public static void main(String[] args) {OnePerson onePerson new OnePerson(艾伦, 男, 15);Person person ProxyUtils.createProxy(onePerson);person.playGame();} } 测试结果 可以看到我们并没有在OnePerson类中修改playGame()方法但是成功地对playGame()方法进行了增强。 五、动态代理在SpringBoot中的应用 动态代理在SpringBoot中就是面向切面编程AOP可以用来记录操作日志、公共字段自动填充等实现。 下面介绍如何实现记录操作日志 导入依赖 !--AOP起步依赖-- dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId /dependency !--fastjson-- dependencygroupIdcom.alibaba/groupIdartifactIdfastjson/artifactIdversion1.2.83/version /dependency 数据库表设计 create table if not exists tb_operate_log (id bigint auto_increment comment 主键idprimary key,class_name varchar(128) not null comment 类名,method_name varchar(128) not null comment 方法名,method_param varchar(1024) not null comment 方法参数,method_return varchar(2048) not null comment 方法返回值,cost_time bigint not null comment 方法运行耗时;单位ms,create_username varchar(16) not null comment 方法调用者用户名,create_time datetime not null comment 创建时间,update_time datetime not null comment 更新时间,constraint idunique (id) )comment 操作日志表; OperateLogEntity实体类 import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;import java.time.LocalDateTime;/*** Description: 操作日志表实体类* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return:*/ Data AllArgsConstructor NoArgsConstructor public class OperateLogEntity {private Long id;private String className;private String methodName;private String methodParam;private String methodReturn;private Long costTime;private String createUsername;private LocalDateTime createTime;private LocalDateTime updateTime; } OperateLog枚举 /*** Description: 日志操作类型* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return:*/ public enum OperateLog {//记录操作RECORD} RecordLog注解 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/*** Description: 注解用于标识需要进行记录操作日志的方法* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return:*/ Target(ElementType.METHOD) Retention(RetentionPolicy.RUNTIME) public interface RecordLog {//日志操作类型RECORD记录操作OperateLog value();} 上下文相关类 ThreadLocal线程局部变量将信息放入上下文后面要用可以直接取出。 public class BaseContext {public static ThreadLocalString threadLocal new ThreadLocal();public static void setContext(String context) {threadLocal.set(context);}public static String getContext() {return threadLocal.get();}public static void removeContext() {threadLocal.remove();} } OperateLogAspect切面类 import com.alibaba.fastjson.JSONObject; import lombok.RequiredArgsConstructor; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.springframework.stereotype.Component;import java.time.LocalDateTime; import java.util.Arrays;/*** Description: 切面类实现记录操作日志* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return:*/ Aspect Component RequiredArgsConstructor public class OperateLogAspect {private final OperateLogMapper operateLogMapper;/*** Description: 切入点* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return: void*/Pointcut(execution(* com.demo.controller.*.*(..)) annotation(com.demo.annotation.RecordLog))public void recordLogPointcut() {}/*** Description: 环绕通知进行记录操作日志* Author: 翰戈.summer* Date: 2023/11/21* Param: ProceedingJoinPoint* Return: Object*/Around(recordLogPointcut())public Object recordLog(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {//获取类名String className proceedingJoinPoint.getTarget().getClass().getName();//获取方法名String methodName proceedingJoinPoint.getSignature().getName();//获取方法参数Object[] args proceedingJoinPoint.getArgs();String methodParam Arrays.toString(args);Long begin System.currentTimeMillis();// 方法运行开始时间Object result proceedingJoinPoint.proceed();// 运行方法Long end System.currentTimeMillis();// 方法运行结束时间//方法耗时Long costTime end - begin;//获取方法返回值String methodReturn JSONObject.toJSONString(result);String username BaseContext.getContext();// 当前用户名LocalDateTime now LocalDateTime.now();// 当前时间OperateLogEntity operateLog new OperateLogEntity(null, className, methodName,methodParam, methodReturn, costTime, username, now, now);operateLogMapper.insertOperateLog(operateLog);return result;} } OperateLogMapper import org.apache.ibatis.annotations.Mapper;/*** Description: 操作日志相关的数据库操作* Author: 翰戈.summer* Date: 2023/11/21* Param:* Return:*/ Mapper public interface OperateLogMapper {void insertOperateLog(OperateLogEntity operateLog); } ?xml version1.0 encodingUTF-8 ? !DOCTYPE mapperPUBLIC -//mybatis.org//DTD Mapper 3.0//ENhttp://mybatis.org/dtd/mybatis-3-mapper.dtdmapper namespacecom.demo.mapper.OperateLogMapper!--记录操作日志--insert idinsertOperateLoginsert into tb_operate_log (id, class_name, method_name, method_param,method_return, cost_time, create_username, create_time, update_time)values (null, #{className}, #{methodName}, #{methodParam},#{methodReturn}, #{costTime}, #{createUsername}, #{createTime}, #{updateTime});/insert /mapper 通过给controller层的接口方法加上RecordLog(OperateLog.RECORD)注解即可实现记录操作日志方便以后的问题排查。 《AOP如何实现公共字段自动填充》 https://blog.csdn.net/qq_74312711/article/details/134702905?spm1001.2014.3001.5502
http://www.dnsts.com.cn/news/212657.html

相关文章:

  • 兰州 网站网站建设开发报价明细
  • 服务器添加网站wordpress 开发飞猪接口
  • 做一个网站开发项目有哪些阶段wordpress分类展示插件
  • 佰联轴承网做的网站简单的html网页
  • 网站网络推广公司做网站需要哪些技术人才
  • 和网站用户体验相关的文章网站建设及推广服务的合同范本
  • 福建seo网站网页加速器手机版
  • 外贸网站推广有哪些科郑州网站建设
  • 河北建设工程信息网正规网站儿童编程网课平台哪个好
  • 网站关键词搜索wordpress 评论者邮箱
  • 东莞公司网站制作公司网页美工设计招聘网
  • 做自己的网站能赚钱吗wordpress 多站点 子目录
  • 做网站有费用吗中国建设报电子版在线阅读
  • 上海建设监理协会网站邢台市疾控中心
  • 前端网站开发框架个人网站搭建平台
  • 长安网站建设软件开发家装网站建设多少钱
  • vvic一起做网站企业网站建设规划的基本原则
  • 5g建设多少网站广州网站seo地址
  • 网站开发界面图标设计重庆那里做网站外包好
  • 陕西 网站备案网络营销外包推广策划方案
  • 网站设计师是什么部门视频app开发制作多少钱
  • 公司网站设计网络公司深圳网站设计兴田德润i优惠吗
  • vs建设网站佛山小程序开发制作
  • 网站宣传制作网站开发 seo
  • 微信公众平台开发微网站网站建设企业
  • 一般网站设计多大宽度什么浏览器好用可以看任何网站
  • 门户网站如何制作wordpress安装主题慢
  • 视频网站开发研究背景建筑机械人才培训网查询官网
  • 泰州公司网站建设建设工程法律网站
  • 无锡网站建设维护wordpress大学主题修改