Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the ways to act as agents

2025-01-22 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "what kind of agent way". In the daily operation, I believe that many people have doubts about what kind of agent way they have. The editor consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the question of "what kind of agent way"! Next, please follow the editor to study!

The way of five kinds of agency

Not surprisingly, you may only know the ways of two kinds of agents. One comes with JDK, and the other is CGLIB.

We first define an interface and the corresponding implementation class to facilitate the subsequent use of the proxy class to add output information to the method.

"define Interface"

Public interface IUserApi {

String queryUserInfo ()

}

"implement Interface"

Public class UserApi implements IUserApi {

Public String queryUserInfo () {

Return "Little Brother Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that you and others can gain something!"

}

}

good! Next we add an extra line of output to the class method using the proxy.

0. First add a little knowledge of reflection @ Test

Public void test_reflect () throws Exception {

Class clazz = UserApi.class

Method queryUserInfo = clazz.getMethod ("queryUserInfo")

Object invoke = queryUserInfo.invoke (clazz.newInstance ())

System.out.println (invoke)

}

Index: ⭐⭐ comments: where there are agents, there will almost be reflections, they are a set of functional classes that cooperate with each other. In reflection, you can call methods, get properties, get annotations, and so on. All of these can be combined with the following class agents to complete the technical scenarios in various frameworks. 1. JDK proxy public class JDKProxy {

Public static T getProxy (Class clazz) throws Exception {

ClassLoader classLoader = Thread.currentThread () .getContextClassLoader ()

Return (T) Proxy.newProxyInstance (classLoader, new Class [] {clazz}, new InvocationHandler () {

Public Object invoke (Object proxy, Method method, Object [] args) throws Throwable {

System.out.println (method.getName () + "you are represented, By JDKProxy!")

Return "Little Brother Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that you and others can gain something!"

}

});

}

}

@ Test

Public void test_JDKProxy () throws Exception {

IUserApi userApi = JDKProxy.getProxy (IUserApi.class)

String invoke = userApi.queryUserInfo ()

Logger.info ("Test results: {}", invoke)

}

/ * *

* Test results:

*

* queryUserInfo, you are represented, By JDKProxy!

* 19Rom 55 main 47.319 [main] INFO org.itstack.interview.test.ApiTest-Test results: Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that both yourself and others can gain something!

*

* Process finished with exit code 0

, /

Index: ⭐⭐ scenarios: middleware development, design patterns in the proxy pattern and decorator pattern application comments: this JDK comes with a class proxy is a very common, but also a very simple one. Basically can be seen in some middleware code, such as: database routing components, Redis components, etc., and we can also use this way to apply to the design pattern. 2. CGLIB proxy public class CglibProxy implements MethodInterceptor {

Public Object newInstall (Object object) {

Return Enhancer.create (object.getClass (), this)

}

Public Object intercept (Object o, Method method, Object [] objects, MethodProxy methodProxy) throws Throwable {

System.out.println ("I am represented by CglibProxy")

Return methodProxy.invokeSuper (o, objects)

}

}

@ Test

Public void test_CglibProxy () throws Exception {

CglibProxy cglibProxy = new CglibProxy ()

UserApi userApi = (UserApi) cglibProxy.newInstall (new UserApi ())

String invoke = userApi.queryUserInfo ()

Logger.info ("Test results: {}", invoke)

}

/ * *

* Test results:

*

* queryUserInfo, you are represented, By CglibProxy!

* 19Rom 55 main 47.319 [main] INFO org.itstack.interview.test.ApiTest-Test results: Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that both yourself and others can gain something!

*

* Process finished with exit code 0

, /

Index: ⭐⭐⭐ scenarios: Spring, AOP aspects, authentication services, middleware development, RPC framework, etc. Comments: CGLIB is different from JDK. Its underlying layer uses the ASM bytecode framework to modify the script in the class to implement a proxy, so this proxy method does not need an interface to proxy like JDK. At the same time, thanks to the use of the bytecode framework, this proxy is 1.5 times faster than using the JDK proxy. 3. ASM proxy public class ASMProxy extends ClassLoader {

Public static T getProxy (Class clazz) throws Exception {

ClassReader classReader = new ClassReader (clazz.getName ())

ClassWriter classWriter = new ClassWriter (classReader, ClassWriter.COMPUTE_MAXS)

ClassReader.accept (new ClassVisitor (ASM5, classWriter) {

@ Override

Public MethodVisitor visitMethod (int access, final String name, String descriptor, String signature, String [] exceptions) {

/ / method filtering

If (! "queryUserInfo" .equals (name))

Return super.visitMethod (access, name, descriptor, signature, exceptions)

Final MethodVisitor methodVisitor = super.visitMethod (access, name, descriptor, signature, exceptions)

Return new AdviceAdapter (ASM5, methodVisitor, access, name, descriptor) {

@ Override

Protected void onMethodEnter () {

/ / execute instructions; get static properties

MethodVisitor.visitFieldInsn (Opcodes.GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;")

/ / load constant load constant

MethodVisitor.visitLdcInsn (name + "you are represented, By ASM!")

/ / call the method

MethodVisitor.visitMethodInsn (Opcodes.INVOKEVIRTUAL, "java/io/PrintStream", "println", "(Ljava/lang/String;) V", false)

Super.onMethodEnter ()

}

}

}

}, ClassReader.EXPAND_FRAMES)

Byte [] bytes = classWriter.toByteArray ()

Return (T) new ASMProxy (). DefineClass (clazz.getName (), bytes, 0, bytes.length). NewInstance ()

}

}

@ Test

Public void test_ASMProxy () throws Exception {

IUserApi userApi = ASMProxy.getProxy (UserApi.class)

String invoke = userApi.queryUserInfo ()

Logger.info ("Test results: {}", invoke)

}

/ * *

* Test results:

*

* queryUserInfo, you are represented, By ASM!

* 20 12 main 26.791 [main] Test results: Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that both yourself and others can gain something!

*

* Process finished with exit code 0

, /

Index: ⭐ scenario: full link monitoring, cracking toolkit, CGLIB, Spring access class metadata, etc. Comments: this kind of agent is processed by bytecode programming, its implementation is relatively complex, and it needs to know the relevant knowledge of Java virtual machine specification. Because every step of your proxy operation, you are operating bytecode instructions, such as Opcodes.GETSTATIC, Opcodes.INVOKEVIRTUAL, in addition to these, there are 200 commonly used instructions. But the way closest to the bottom is also the fastest way. Therefore, it is very common in some full-link monitoring using bytecode instrumentation. 4. Byte-Buddy proxy public class ByteBuddyProxy {

Public static T getProxy (Class clazz) throws Exception {

DynamicType.Unloaded dynamicType = new ByteBuddy ()

.subclass (clazz)

.method (ElementMatchers.named ("queryUserInfo"))

.intercept (MethodDelegation.to (InvocationHandler.class))

.make ()

Return (T) dynamicType.load (Thread.currentThread (). GetContextClassLoader ()). GetLoaded (). NewInstance ()

}

}

@ RuntimeType

Public static Object intercept (@ Origin Method method, @ AllArguments Object [] args, @ SuperCall Callable callable) throws Exception {

System.out.println (method.getName () + "you are represented, By Byte-Buddy!")

Return callable.call ()

}

@ Test

Public void test_ByteBuddyProxy () throws Exception {

IUserApi userApi = ByteBuddyProxy.getProxy (UserApi.class)

String invoke = userApi.queryUserInfo ()

Logger.info ("Test results: {}", invoke)

}

/ * *

* Test results:

*

* queryUserInfo, you are represented, By Byte-Buddy!

* 20Rd 19VR 44.498 [main] INFO org.itstack.interview.test.ApiTest-Test results: Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that both yourself and others can gain something!

*

* Process finished with exit code 0

, /

Index: ⭐⭐⭐⭐ scenarios: AOP aspects, class agents, components, monitoring, log comments: Byte Buddy is also a class library for bytecode operation, but the way to use Byte Buddy is simpler. Without understanding bytecode instructions, you can easily manipulate bytecode, control classes, and methods using a simple API. Compared with JDK dynamic agent and cglib,Byte Buddy, it has some advantages in performance. In addition, Byte Buddy was awarded the Duke's Choice Award by Oracle in October 2015. The award appreciates Byte Buddy's "tremendous innovation in Java technology". 5. Javassist proxy public class JavassistProxy extends ClassLoader {

Public static T getProxy (Class clazz) throws Exception {

ClassPool pool = ClassPool.getDefault ()

/ / get the class

CtClass ctClass = pool.get (clazz.getName ())

/ / acquisition method

CtMethod ctMethod = ctClass.getDeclaredMethod ("queryUserInfo")

/ / strengthen before the method

CtMethod.insertBefore ("{System.out.println (\"+ ctMethod.getName () +" you are represented, By Javassist\ ");}")

Byte [] bytes = ctClass.toBytecode ()

Return (T) new JavassistProxy (). DefineClass (clazz.getName (), bytes, 0, bytes.length). NewInstance ()

}

}

@ Test

Public void test_JavassistProxy () throws Exception {

IUserApi userApi = JavassistProxy.getProxy (UserApi.class)

String invoke = userApi.queryUserInfo ()

Logger.info ("Test results: {}", invoke)

}

/ * *

* Test results:

*

* queryUserInfo, you are represented, By Javassist

* 20Rd 23 main 39.139 [main] INFO org.itstack.interview.test.ApiTest-Test results: little Brother Fu, official account: bugstack wormhole stack | precipitate, share and grow, so that you and others can gain something!

*

* Process finished with exit code 0

, /

Index: ⭐⭐⭐⭐ scenario: full-link monitoring, class agent, AOP comments: Javassist is a widely used bytecode instrumentation framework, almost a large part of non-invasive full-link monitoring will choose to use this framework. Because it is not as risky to manipulate bytecode as ASM does, and it is also very functional. In addition, this framework can not only use the way it provides to write plug-in code directly, but also use bytecode instructions to control the generation of code, so it is also a very good bytecode framework. The actual purpose of summarizing the agent is to replace the original implementation class or inject new bytecode instructions into the original implementation class through some technical means. These technologies will eventually be used in some framework applications, middleware development and similar non-invasive full-link monitoring. An in-depth study of the technology stack can give you a thorough understanding of some basic principles, through which you can solve some seemingly incomprehensible questions, and you can also have better job opportunities and salaries through the expansion of this technology. These techniques are not easy to learn, and there may even be some brain-burning. But every piece of technology worth learning in depth can help you break through the technical bottleneck at a certain stage. At this point, the study of "what kinds of agency ways" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report