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/
转载文章受原作者版权保护。转载请注明原作者出处!