【年度钻石】Linux云计算+运维(1)《博学谷》黑马

Java互联网企业架构技术VIP课程【腾讯课堂每特】

Java互联网企业架构技术VIP课程【腾讯课堂每特】

课程 内容

站在架构角度,基于装饰模式纯手写设计多级缓存框架

本节课需要知识:动态代理技术+Aop+装饰模式+Redis缓存概念

注意 :因为该 设计模式比较 接近真实案例,需要有 S pringBoot基础。

创建型 模式

工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型 模式

适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式

行为 模式

策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

什么是代理模式

代理模式主要对我们方法执行之前与之后实现增强

代理模式应用场景

代理模式创建方式

静态代理需要自己人工编写代理类代码

public classOrderServiceProxy implementsOrderService{
privateOrderService orderService;

publicOrderServiceProxy(OrderService orderService) {
this. orderService= orderService;
}

publicString addOrder(String userName, String userPwd) {
System. out.println( 使用静态代理类打印日志开始: userName:”+ userName + “,”+ userPwd);
String result = orderService.addOrder(userName, userPwd);
System. out.println( 使用静态代理类打印日志结束: userName:”+ userName + “,”+ userPwd);
returnresult;
}
}

public interfaceOrderService {
/ _需要被代理的方法 __ @return_* _/_String addOrder(String userName,String userPwd);
}

public classTest001 {
public static voidmain(String[] args) {
OrderService orderService = newOrderServiceProxy(newOrderServiceImpl());
orderService.addOrder(“mayikt”, “123456”);
}
}

public classOrderServiceProxy extendsOrderServiceImpl {
privateOrderService orderService;

publicOrderServiceProxy(OrderService orderService) {
this. orderService= orderService;
}

publicString addOrder(String userName, String userPwd) {
System. out.println( 使用静态代理类打印日志开始: userName:”+ userName + “,”+ userPwd);
String result = super.addOrder(userName, userPwd);
System. out.println( 使用静态代理类打印日志结束: userName:”+ userName + “,”+ userPwd);
returnresult;
}
}

动态代理不需要写代理类对象,通过程序自动生成,而静态代理需要我们自己写代理类对象。

动态代理是在实现阶段不用关心代理类,而在运行阶段才指定哪一个对象。

动态代理类的源码是在程序运行期间由JVM根据反射等机制动态的生成 。

JDK动态代理的一般步骤如下:

1.创建被代理的接口和类;

2.实现InvocationHandler接口,对目标接口中声明的所有方法进行统一处理;

3.调用Proxy的静态方法,创建代理类并生成相应的代理对象;

实现原理:利用拦截器机制必须实现InvocationHandler接口中的invoke方法实现对

我们的目标方法增强。

public classJdkInvocationHandler implementsInvocationHandler {
_/ _目标对象 _/_ privateObject target**;

publicJdkInvocationHandler(Object target) {
this. target= target;
}

/ *_ @param_ proxy 使用 jdk 程序生成的代理类 * @param method 目标方法 * @param args 方法需要传递的参数 * @return */ publicObject invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System.
out.println( 使用 Jdk 动态代理打印日志开始 + args[0]);
Object result = method.invoke(
target, args);
System.
out.println( 使用 Jdk 动态代理打印日志结束 + args[1]);
return**result;
}

/ _生成代理类 _ *_ @param_ * @return */ public**

public classJdkInvocationHandler implementsInvocationHandler {
_/ _目标对象 _/_ privateObject target**;

publicJdkInvocationHandler(Object target) {
this. target= target;
}

/ *_ @param_ proxy 使用 jdk 程序生成的代理类 * @param method 目标方法 * @param args 方法需要传递的参数 * @return */ publicObject invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System.
out.println( 使用 Jdk 动态代理打印日志开始 + args[0]);
Object result = method.invoke(
target, args);
System.
out.println( 使用 Jdk 动态代理打印日志结束 + args[1]);
return**result;
}

public

JdkInvocationHandler jdkInvocationHandler = newJdkInvocationHandler(newOrderServiceImpl());
OrderServiceImpl orderService = jdkInvocationHandler.getProxy();
orderService.addOrder(“mayikt”, “meite”);

加上该代码:

System.getProperties().put(“sun.misc.ProxyGenerator.saveGeneratedFiles”, “true”);

注意:继承了Proxy类,实现了代理的接口,由于java不能多继承,这里已经继承了Proxy类了,不能再继承其他的类,所以JDK的动态代理不支持对实现类的代理,只支持接口的代理。

思路分析:

public class$Proxy0 implementscom.mayikt.service.OrderService {

privateMayiktJdkInvocationHandler h;
private staticMethod m3;

public$Proxy0(MayiktJdkInvocationHandler mayiktJdkInvocationHandler) {
this. h= mayiktJdkInvocationHandler;
}

@Override
publicString addOrder(String ver1, String var2) {
try{
return(String) h.invoke(this, m3, newObject[]{ver1, var2});
} catch(RuntimeException | Error var4) {
throwvar4;
} catch(Throwable var5) {
throw newUndeclaredThrowableException(var5);
}
}

static{
try{
m3= Class. forName(“com.mayikt.service.OrderService”).getMethod(“addOrder”, Class. forName(“java.lang.String”), Class. forName(“java.lang.String”));
} catch(NoSuchMethodException var2) {
throw newNoSuchMethodError(var2.getMessage());
} catch(ClassNotFoundException var3) {
throw newNoClassDefFoundError(var3.getMessage());
}
}
}

public classMyJdkInvocationHandler implementsMayiktJdkInvocationHandler {
_/ _目标对象 _/_ privateObject target**;

publicMyJdkInvocationHandler(Object target) {
this. target= target;
}

@Override
publicObject invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System. out.println( 使用 Jdk 动态代理打印日志开始 + args[0]);
Object result = method.invoke(target, args);
System. out.println( 使用 Jdk 动态代理打印日志结束 + args[1]);
returnresult;
}
public

MyJdkInvocationHandler myJdkInvocationHandler = newMyJdkInvocationHandler(newOrderServiceImpl());
OrderService orderService = myJdkInvocationHandler.getProxy();
orderService.addOrder(“mayikt”, “meite”);

public classMyProxy {
private staticString rt= \r\t ;

public staticObject newProxyInstance(JavaClassLoader classLoader, Class classInfo, MayiktInvocationHandler mayiktInvocationHandler) {
try{
// 1. 拼接 java 代理代理源代码_Method[] methods = classInfo.getMethods();
String proxyClass = “package com.mayikt.service;”+ _rt
+ “import java.lang.reflect.Method;”+ rt+ “import com.mayikt.service.proxy.MayiktInvocationHandler;”+ rt+ “import java.lang.reflect.UndeclaredThrowableException;”+ rt+ “public class $Proxy0 implements “+ classInfo.getName() + “{“+ rt+ “MayiktInvocationHandler h;”+ rt+ “public $Proxy0(MayiktInvocationHandler h)”+ “{“+ rt+ “this.h= h;”+ rt+ “}”+ getMethodString(methods, classInfo) + rt+ “}”;
// 2. 将该源代码写入到本地文件中_String filename = “d:/code/$Proxy0.java”;
File f = newFile(filename);
FileWriter fw = newFileWriter(f);
fw.write(proxyClass);
fw.flush();
fw.close();
// 3. _编译为 class 文件_JavaCompiler compiler = ToolProvider. _getSystemJavaCompiler();
StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null);
Iterable units = fileMgr.getJavaFileObjects(filename);
JavaCompiler.CompilationTask t = compiler.getTask(null, fileMgr, null, null, null, units);
t.call();
fileMgr.close();
// 4. class 文件加入到内存中_Class proxy0Class = classLoader.findClass(“$Proxy0”);
//5. _使用 java _反射机制给函数中赋值_Constructor m = proxy0Class.getConstructor(MayiktInvocationHandler. class);
Object object = m.newInstance(mayiktInvocationHandler);
returnobject;
} catch(Exception e) {
return null;
}
}

public staticString getMethodString(Method[] methods, Class intf) {
String proxyMe = “”;

for(Method method : methods) {
Class[] parameterTypes = method.getParameterTypes();
StringBuilder sb = newStringBuilder();
for(inti = 0; i < parameterTypes. length; i++) {
sb.append(parameterTypes[i].getName() + ” ver”+ (i + 1));
if(i < parameterTypes. length– 1) {
sb.append(” ,”);
}
}
String parameterStr = sb.toString();
proxyMe = “public “+ method.getReturnType().getName() + ” “+ method.getName() + ” ( “+ parameterStr + ” ) { “+
“try { Method m3 = Class.forName( \” com.mayikt.service.OrderService \” ).getMethod( \” addOrder \” , Class.forName( \” java.lang.String \” ), Class.forName( \” java.lang.String \” ));”+
“return (String) h.invoke(this, m3, new Object[]{ver1, ver2}); } catch (RuntimeException | Error var4) { throw var4; } catch (Throwable var5) { throw new UndeclaredThrowableException(var5); } “+
“”+
” } “;

}
returnproxyMe;
}

public static voidmain(String[] args) {
newProxyInstance(null, OrderService. class, null);
}
}

public classJavaClassLoader extendsClassLoader {

privateFile classPathFile;

publicJavaClassLoader(){
_// String classPath=JavaClassLoader.class.getResource(“”).getPath();_String classPath= “D: \ code”;
this. classPathFile= newFile(classPath);
}

@Override
publicClass findClass(String name) throwsClassNotFoundException {
String className= JavaClassLoader. class.getPackage().getName()+ “.”+name;
if(classPathFile!= null){
File classFile= newFile(classPathFile,name.replaceAll( \ .”, “/”)+ “.class”);
if(classFile.exists()){
FileInputStream in= null;
ByteArrayOutputStream out= null;
try{
in= newFileInputStream(classFile);
out= newByteArrayOutputStream();
byte[] buff= new byte[1024];
intlen;
while((len=in.read(buff))!=-1){
out.write(buff,0,len);
}
returndefineClass(className,out.toByteArray(),0,out.size());
} catch(Exception e){
e.printStackTrace();
} finally{
if(in!= null){
try{
in.close();
} catch(IOException e) {
e.printStackTrace();
}
}
if(out!= null){
try{
out.close();
} catch(IOException e) {
e.printStackTrace();
}
}
}
}
}
return null;
}
}

public classMyJdkInvocationHandler implementsMayiktJdkInvocationHandler {
_/ _目标对象 _/_ privateObject target**;

publicMyJdkInvocationHandler(Object target) {
this. target= target;
}

@Override
publicObject invoke(Object proxy, Method method, Object[] args) throwsThrowable {
System. out.println( 使用 Jdk 动态代理打印日志开始 + args[0]);
Object result = method.invoke(target, args);
System. out.println( 使用 Jdk 动态代理打印日志结束 + args[1]);
returnresult;
}

public

利用asm字节码技术,生成子类实现对目标方法实现增强

< dependencies>
< dependency>
< groupId>cglibgroupId>
< artifactId>cglibartifactId>
< version>3.2.12version>
dependency>
dependencies>

public classCglibMethodInterceptor implementsMethodInterceptor {
publicObject intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throwsThrowable {
System. out.println(“<<<<< 日志收集开始 …>>>>>>>”);
Object reuslt = proxy.invokeSuper(obj, args);
System. out.println(“<<<<< 日志收集结束 …>>>>>>>”);
returnreuslt;
}
}

System. setProperty(DebuggingClassWriter. DEBUG_LOCATION_PROPERTY, “D: \ code”);
CglibMethodInterceptor cglibMethodInterceptor = newCglibMethodInterceptor();
Enhancer enhancer = newEnhancer();
// 设置代理类的付类_enhancer.setSuperclass(MemberServiceImpl. class);
// _设置回调对象_enhancer.setCallback(cglibMethodInterceptor);
//_ _创建代理对象_MemberServiceImpl orderServiceImpl = (MemberServiceImpl) enhancer.create();
orderServiceImpl.getMember();

Cglib依赖于ASM字节码技术,直接生成class文件,在采用类加载器读取到程序中,

使用fastclass对被代理类的方法建立索引文件不需要依赖于反射查找到目标方法,所以效率比Jdk动态代理要高。

public classOrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c extendsOrderServiceImpl {

static voidCGLIB$STATICHOOK1() throwsClassNotFoundException {
Method amethod[];
Method amethod1[];
CGLIB$THREAD_CALLBACKS= newThreadLocal();
CGLIB$emptyArgs= newObject[0];
Class class1 = Class. forName(“com.mayikt.service.impl.OrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c”);
Class class2;
amethod = ReflectUtils. findMethods(newString[]{
“addOrder”, “(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;”}, (class2 = Class. forName(“com.mayikt.service.impl.OrderServiceImpl”)).getDeclaredMethods());
Method[] tmp = amethod;
_CGLIB$addOrder$0$Method
= amethod[0];
CGLIB$addOrder$0$Proxy= MethodProxy. create(class2, class1, “(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;”, “addOrder”, “CGLIB$addOrder$0”);
amethod1 = ReflectUtils. findMethods(newString[]{
“equals”, “(Ljava/lang/Object;)Z”, “toString”, “()Ljava/lang/String;”, “hashCode”, “()I”, “clone”, “()Ljava/lang/Object;”}, (class2 = Class. forName(“java.lang.Object”)).getDeclaredMethods());
Method[] tmp1 = amethod1;
_CGLIB$equals$1$Method
= amethod1[0];
CGLIB$equals$1$Proxy= MethodProxy. create(class2, class1, “(Ljava/lang/Object;)Z”, “equals”, “CGLIB$equals$1”);
CGLIB$toString$2$Method= amethod1[1];
CGLIB$toString$2$Proxy= MethodProxy. create(class2, class1, “()Ljava/lang/String;”, “toString”, “CGLIB$toString$2”);
CGLIB$hashCode$3$Method= amethod1[2];
CGLIB$hashCode$3$Proxy= MethodProxy. create(class2, class1, “()I”, “hashCode”, “CGLIB$hashCode$3”);
CGLIB$clone$4$Method= amethod1[3];
CGLIB$clone$4$Proxy= MethodProxy. create(class2, class1, “()Ljava/lang/Object;”, “clone”, “CGLIB$clone$4”);
}

finalString CGLIB$addOrder$0(String s, String s1) {
return super.addOrder(s, s1);
}

final booleanCGLIB$equals$1(Object obj) {
return super.equals(obj);
}

finalString CGLIB$toString$2() {
return super.toString();
}

final intCGLIB$hashCode$3() {
return super.hashCode();
}

public static voidCGLIB$SET_THREAD_CALLBACKS(Callback acallback[]) {
CGLIB$THREAD_CALLBACKS.set(acallback);
}

public finalString addOrder(String paramString1, String paramString2) {
MethodInterceptor tmp4_1 = this. CGLIB$CALLBACK_0;
if(tmp4_1 == null) {

CGLIB$BIND_CALLBACKS(this);
}
try{
MethodInterceptor tmp17_14 = this. CGLIB$CALLBACK_0;
if(tmp17_14 != null) {
return(String) tmp17_14.intercept(this, CGLIB$addOrder$0$Method, newObject[]{paramString1, paramString2}, CGLIB$addOrder$0$Proxy);
}
} catch(Throwable throwable) {
throwable.printStackTrace();
}
return super.addOrder(paramString1, paramString2);
}

publicObject newInstance(Callback acallback[]) {
CGLIB$SET_THREAD_CALLBACKS(acallback);
CGLIB$SET_THREAD_CALLBACKS(null);
return newOrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c();
}

publicObject newInstance(Callback callback) {
CGLIB$SET_THREAD_CALLBACKS(newCallback[]{
callback
});
CGLIB$SET_THREAD_CALLBACKS(null);
return newOrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c();
}

public voidsetCallback(inti, Callback callback) {
switch(i) {
case0: // ‘\0’ CGLIB$CALLBACK_0= (MethodInterceptor) callback;
break;
}
}

private boolean CGLIB$BOUND;
public staticObject CGLIB$FACTORY_DATA;
private staticThreadLocal CGLIB$THREAD_CALLBACKS= null;
private static finalCallback CGLIB$STATIC_CALLBACKS[] = null;
privateMethodInterceptor CGLIB$CALLBACK_0;
private staticObject CGLIB$CALLBACK_FILTER;
private staticMethod CGLIB$addOrder$0$Method= null;
private staticMethodProxy CGLIB$addOrder$0$Proxy= null;
private staticObject[] CGLIB$emptyArgs= null;
private staticMethod CGLIB$equals$1$Method= null;
private staticMethodProxy CGLIB$equals$1$Proxy= null;
private staticMethod CGLIB$toString$2$Method= null;
private staticMethodProxy CGLIB$toString$2$Proxy= null;
private staticMethod CGLIB$hashCode$3$Method= null;
private staticMethodProxy CGLIB$hashCode$3$Proxy= null;
private staticMethod CGLIB$clone$4$Method= null;
private staticMethodProxy CGLIB$clone$4$Proxy= null;

static{
try{
CGLIB$STATICHOOK1();
} catch(ClassNotFoundException e) {
e.printStackTrace();
}
}

publicOrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c() {
CGLIB$BIND_CALLBACKS(this);
}

private voidCGLIB$BIND_CALLBACKS(OrderServiceImpl$$EnhancerByCGLIB$$1dd3a71c orderServiceImpl$$EnhancerByCGLIB$$1dd3a71c) {
}
}

public classMayiktFastclass {

/ _根据索引查找到目标方法 _ *_ @param_ index * @param obj * @param args * @return */ public staticObject invoke(intindex, Object obj, Object[] args) {
OrderServiceImpl orderService = (OrderServiceImpl) obj;
switch(index) {
case1:
returnorderService.addOrder(String. valueOf(args[0]), String. valueOf(args[1]));
}
return null**;
}

/ _根据签名简历索引文件 _ *_ @param_ sign * @return */ public static intgetIndex(String sign) {
switch(sign.hashCode()) {
case1763340254:
return1;
case20:
return2;
}
return**-1;
}

public static voidmain(String[] args) {
System. out.println(“addOrder()String,String”.hashCode());
Object result = invoke(getIndex(“addOrder()String,String”), newOrderServiceImpl(), newString[]{ “mayikt”, “meite”});
}
}

Original: https://www.cnblogs.com/itit9696/p/15130080.html
Author: cml46679910
Title: 【年度钻石】Linux云计算+运维(1)《博学谷》黑马

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/579352/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • Javafx-【直方图】文本频次统计工具 中文/英文单词统计

    上周倒腾了下 javafx,本来是做平时成绩系统。跟老师提了一下 javafx,他突然兴起,发了个统计中文和英文单词并以直方图显示的实验……只给两三天的期限…

    Java 2023年6月5日
    0118
  • Java之万年历

    @ 二、Java之万年历 2.1 要求 2.2 思路 2.3 源代码 2.4 结果截图 二、Java之万年历 2.1 要求 输入年份; 输入月份; 输出某年某月的日历。 2.2 思…

    Java 2023年6月5日
    0112
  • openresty IP限流

    1、针对大流量大并发网络请求下,为了保证服务的正常运行,不得不针对性采取限流的方式来解决大流量带来的服务器的压力。 2、在目前项目中对于接入了不同的平台,所以需要针对具体的平台做相…

    Java 2023年6月8日
    087
  • JDK成长记13:(深度好文)你能从3个层面分析volatile底层原理么?(上)

    前几节你应该学习到了Thread和ThreadLocal的底层原理,在接下来的几节中,让我们一起来探索volatile底层原理吧! 不知道你有没有这样的感受:有很多工程师都很难说清…

    Java 2023年6月5日
    082
  • SpringCloud学习笔记-Eureka基础

    Spring Cloud Eureka是Spring Cloud Netflix微服务套件中的一部分,它基于Netflix Eureka做了二次封装,主要负责完成微服务架构中的微服…

    Java 2023年5月30日
    099
  • 深入MySQL(一):MySQL的组织架构

    今天开始将自己所学过的MySQL的知识都尝试融会贯通,并且用写博客的方式记录分享下来。今天讲的主题是 MySQL的组织架构,对于学习一个中间件或者开源项目而言,我觉得最重要的便是先…

    Java 2023年6月7日
    0104
  • SpringBoot集成thymeleaf模板

    1.在pom文件添加: org.springframework.boot spring-boot-starter-thymeleaf2.在html页面的头部添加 3.在java C…

    Java 2023年6月14日
    069
  • 生产计划体系完整解决方案(1)-复杂大规模问题的分阶段规划

    背景 在过往参与的一些项目支持工作,以及平台发布后各位小伙伴使用过程中,经常遇到这样的问题:你这个引擎性能怎么样?可以处理多大数据量的排程?我有数万个任务,这个引擎多长时间可以排产…

    Java 2023年6月16日
    0105
  • 【Java面试手册-算法篇】给定一个整型数组,请判断是否为回文数组?

    对于一个给定的由正整数组成的数组 A[] ,如果将 A 倒序后数字的排列与 A 完全相同,则成数组A为回文数组。比如 [1, 2, 3, 2, 1] 是回文数组,而 [1, 2, …

    Java 2023年6月8日
    0108
  • CentOS 6快捷安装RabbitMQ教程

    1.安装Erlang yum install erlang 2.安装RabbitMQ yum install rabbitmq-server 3.配置开机自启动 chkconfig…

    Java 2023年5月29日
    077
  • Redis详解

    1.Redis 是一个基于内存的高性能 key-value 数据库。是完全开源免费的,用C语言编写的,遵守BSD协议 2.Redis 特点: 1)Redis 是基于内存操作的,吞吐…

    Java 2023年6月16日
    080
  • Java核心技术-Lambda

    lambda表达式就是一个代码块以及必须传入代码的变量规范。lambda表达式就是把一个代码块作为参数,放在参数列表里面进行传递,共这个方法使用。数学上带参数变量的表达式就成为la…

    Java 2023年6月5日
    074
  • Starting MySQL… ERROR! The server quit without updating PID file 问题解决

    今天遇到一个mysql起不来,不知为啥挂了,启动是下面的报错Starting MySQL… ERROR! The server quit without updatin…

    Java 2023年6月5日
    058
  • Spring系列15:Environment抽象

    本文内容 Environment抽象的2个重要概念 @Profile 的使用 @PropertySource 的使用 Environment抽象的2个重要概念 Environmen…

    Java 2023年6月5日
    0129
  • Python数据库编程

    1.什么是MySQLdb? 2.如何连接数据库? 3.如何创建数据库表? 4.如何执行数据插入? 5.如何执行数据库查询操作? 6.如何更新数据库数据? 7.如何删除数据库数据? …

    Java 2023年6月7日
    086
  • 如何把Spring学精通了?

    作为 Java 后端工程师,几乎都要用到 Spring,今天这篇文章是和大家说说如何学好 Spring。 在之前的一篇 Java 读书路线的文章中,我介绍过 Spring 的读书路…

    Java 2023年6月7日
    066
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球