【年度钻石】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)

大家都在看

  • Centos安装Cloudera Manager 6.3.0和CDH 6.3.2

    前言 闲暇之时,羚羊给大家分享一下羚羊在Centos7 下安装Cloudera Manager 6.3.0和cloudera cdh 6.3.2的过程和安装过程中遇到的坑。至于为什…

    Java 2023年6月6日
    068
  • Oracle 序列学习与使用总结

    by:授客 QQ:1033553122 序列是oracle提供的用于生成一系列数字的数据库对象,序列会自动生成顺序递增的序列号,可用于提供唯一的自动递增主键。序列和视图一样,并不占…

    Java 2023年6月16日
    061
  • JDBC学习

    笔记如上 学了个代码 php;gutter:true; import java.sql.*;</p> <p>public class jdbc01 { pu…

    Java 2023年6月9日
    076
  • 让工作事半功倍的常用思考框架及关于方法论的思考

    我们真正需要的不是方法论,而是明察秋毫、洞若观火的观察力和感受力。 基本原理 结构化分析法则:从事物或活动中抽取要素及关联,围绕要素和关联构成骨架结构,填充血肉,呈现内容。 多维度…

    Java 2023年6月9日
    067
  • spring cloud 分布式事务 seata

    seata安装与部署 什么是seata? Seata是阿里开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。 官方中文文档:https://seata.io/z…

    Java 2023年6月5日
    0123
  • java中Random类的使用

    Random类用来生成随机数字 Random类的使用步骤 导包 import java.util.Random; 创建对象 Random r = new Random(); 使用 …

    Java 2023年6月7日
    090
  • 前端练习(模仿菜鸟编程网站搭建)

    先看效果: 部分代码: 基本上实现了所有效果 ,目前还有一些小细节存在不足,正在改进中。。。 有需要源码的请留言,共同学习,共同进步。 Original: https://www….

    Java 2023年6月5日
    075
  • 面试题:sleep() 和 wait()的区别?

    1.相同点: 一旦执行方法,都可以使得当前的线程进入阻塞状态。 2.不同点: 1)两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()2…

    Java 2023年6月14日
    067
  • 【设计模式】Java设计模式-组合模式

    Java设计模式 – 组合模式 😄 不断学习才是王道🔥 继续踏上学习之路,学之分享笔记👊 总有一天我也能像各位大佬一样🏆原创作品,更多关注我CSDN: 一个有梦有戏的人…

    Java 2023年6月16日
    092
  • Vue中关于this指向的问题

    例如: computed 计算属性 watch 监视属性 filters (Vue3&#x4E2D;&#x5DF2;&#x5F03;&#x7528;…

    Java 2023年6月9日
    083
  • 解决 idea无法下载源码 Sources not found for:XXX

    解决 idea无法下载源码 Sources not found for:XXX命令行输入 mvn dependency:resolve -Dclassifier=sources 参…

    Java 2023年6月9日
    057
  • springboot中@Configuration的用法

    一、背景在spring框架中,会有大量 的xml配置文件,或者需要做很多繁琐的配置。 从spring3开始,spring就支持了两种bean的配置方式, 一种是基于xml文件方式、…

    Java 2023年5月30日
    064
  • 头秃了,二十三张图带你从源码了解Spring Boot 的启动流程~

    前言 源码版本 从哪入手? 源码如何切分? 如何创建SpringApplication? 设置应用类型 设置初始化器(Initializer) 设置监听器(Listener) 设置…

    Java 2023年6月14日
    080
  • Oracle 查看哪个表被锁定,并获取对应的sessionID

    SELECT A.OWNER,A.OBJECT_NAME,B.XIDUSN,B.XIDSLOT,B.XIDSQN,B.SESSION_ID,B.ORACLE_USERNAME,B….

    Java 2023年5月30日
    073
  • java基本数据类型之间的转换

    基本数据类型之间的相互转换分为两种,分别是自动类型转换和强制类型转换。 自动类型转换 当需要从低级类型向高级类型转换时,java会自动完成从低级类型向高级类型转换。低级类型是指取值…

    Java 2023年6月7日
    076
  • IO流整的明明白白!

    ​ File课理解为文件和文件夹(目录),用于表示磁盘中某个文件或文件夹的路径。该类包含了文件的创建、删除、重命名、判断是否存在等方法。 ​ 只能设置和获取文件本身的信息(文件大小…

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