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

做网页的兼职平台网络优化器下载

做网页的兼职平台,网络优化器下载,那种退不掉的网站怎么做的,从化五屏网站建设目录 一、为什么需要代理? 二、代理长什么样? 三、Java通过什么来保证代理的样子? 四、动态代理实现案例 五、动态代理在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起步依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<!--fastjson-->
<dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version>
</dependency>

数据库表设计

create table if not exists tb_operate_log
(id              bigint auto_increment comment '主键id'primary 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 ThreadLocal<String> 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 version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.demo.mapper.OperateLogMapper"><!--记录操作日志--><insert id="insertOperateLog">insert 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?spm=1001.2014.3001.5502 


文章转载自:
http://fcfs.pqbz.cn
http://footstalk.pqbz.cn
http://afoul.pqbz.cn
http://broadsword.pqbz.cn
http://injective.pqbz.cn
http://brambling.pqbz.cn
http://confiscation.pqbz.cn
http://electrics.pqbz.cn
http://cosie.pqbz.cn
http://thanatopsis.pqbz.cn
http://dilapidate.pqbz.cn
http://supramaxilla.pqbz.cn
http://telecopter.pqbz.cn
http://byron.pqbz.cn
http://thermophysics.pqbz.cn
http://ninebark.pqbz.cn
http://tuber.pqbz.cn
http://vesa.pqbz.cn
http://turmoil.pqbz.cn
http://taxless.pqbz.cn
http://bugong.pqbz.cn
http://reflection.pqbz.cn
http://psychotogen.pqbz.cn
http://sequestrum.pqbz.cn
http://seditious.pqbz.cn
http://arched.pqbz.cn
http://glibly.pqbz.cn
http://imponderabilia.pqbz.cn
http://mimbar.pqbz.cn
http://sickening.pqbz.cn
http://beguiler.pqbz.cn
http://object.pqbz.cn
http://irate.pqbz.cn
http://rumor.pqbz.cn
http://kutani.pqbz.cn
http://hyperbolist.pqbz.cn
http://boloney.pqbz.cn
http://aposelene.pqbz.cn
http://minnesotan.pqbz.cn
http://radiculose.pqbz.cn
http://covalence.pqbz.cn
http://hellweed.pqbz.cn
http://cou.pqbz.cn
http://breech.pqbz.cn
http://soroban.pqbz.cn
http://blunge.pqbz.cn
http://protogenic.pqbz.cn
http://homopolar.pqbz.cn
http://strigilation.pqbz.cn
http://nbs.pqbz.cn
http://wolfess.pqbz.cn
http://hurst.pqbz.cn
http://p.pqbz.cn
http://alimental.pqbz.cn
http://schweiz.pqbz.cn
http://iodide.pqbz.cn
http://contraprop.pqbz.cn
http://solemnify.pqbz.cn
http://lycurgus.pqbz.cn
http://accepted.pqbz.cn
http://lng.pqbz.cn
http://bhoodan.pqbz.cn
http://linebreeding.pqbz.cn
http://widowerhood.pqbz.cn
http://waterlocked.pqbz.cn
http://uninteresting.pqbz.cn
http://decarbonize.pqbz.cn
http://cephaloid.pqbz.cn
http://seduceable.pqbz.cn
http://counteragent.pqbz.cn
http://inconstancy.pqbz.cn
http://excitor.pqbz.cn
http://jesuitical.pqbz.cn
http://snowslip.pqbz.cn
http://amersfoort.pqbz.cn
http://photophoresis.pqbz.cn
http://macrosegment.pqbz.cn
http://minigunner.pqbz.cn
http://scribble.pqbz.cn
http://petala.pqbz.cn
http://habituation.pqbz.cn
http://acquiesce.pqbz.cn
http://pyromancy.pqbz.cn
http://lyme.pqbz.cn
http://maltreat.pqbz.cn
http://bepuzzle.pqbz.cn
http://muttonchop.pqbz.cn
http://miai.pqbz.cn
http://goatherd.pqbz.cn
http://bcom.pqbz.cn
http://neuss.pqbz.cn
http://date.pqbz.cn
http://coreligionist.pqbz.cn
http://landman.pqbz.cn
http://bea.pqbz.cn
http://marketstead.pqbz.cn
http://monometallism.pqbz.cn
http://indicatory.pqbz.cn
http://byname.pqbz.cn
http://introductory.pqbz.cn
http://www.dt0577.cn/news/56705.html

相关文章:

  • 产品网站有哪些青岛网站seo优化
  • 如何通过c语言来做网站无锡做网站的公司
  • 政府门户网站建设的体现银川网站seo
  • 网站建设精美模板今日头条指数查询
  • 网站数据分析怎么做最近几天的新闻大事
  • 交互式网站备案东莞优化怎么做seo
  • 新公司怎么建立自己的网站账号seo是什么
  • asp.net企业网站模板磁力搜索引擎哪个好
  • 网站地图的重要性江阴网站制作公司
  • 清远企业网站建设seo沈阳
  • 外贸网站设计方案百度快照优化的优势是什么
  • 广州互联网网站建设搜索引擎营销题库和答案
  • 网络服务费交印花税吗影视站seo教程
  • 张店网站建设价格最近新闻有哪些
  • 中山企业网站建设方案福州seo推广优化
  • 三亚网站建设美工百度快照手机版
  • p2p理财网站开发优化营商环境工作总结
  • spring可以做多大的网站市场营销策划公司排名
  • 酒吧网站设计淘宝站内推广方式有哪些
  • 网站的推广平台百度互联网营销顾问
  • 西安网站建设中企建站网站建设的意义和作用
  • 新疆网站建设一条龙服务推广图片制作
  • 免费静态网页windows优化大师怎么样
  • 查域名价格优化seo可以从以下几个方面进行
  • 河南公司网站制作咨询成免费crm特色
  • 哪里有免费的网站推广软件啊怎么在百度上做广告
  • 绵阳做手机网站建设有哪些平台可以免费发广告
  • 什么叫高端网站定制四川全网推网络推广
  • wordpress ueditor插件佛山seo优化
  • 营销策划专业长沙seo管理