Abstract

  • Demonstrate static and dynamic proxies respectively

Static agent

Manual proxy

interface

public interface Interface_ {
    public void do(a);
}
Copy the code

Classes that need to be strengthened

public class Object_ implements Interface_{
    @Override
    public void do(a) {
        System.out.println("do"); }}Copy the code

The proxy class

public class Object_Agent implements Interface_{

    private Object_ object_;
    public Object_Agent(Object_ object_) {
        this.object_ = object_;
    }

    @Override
    public  void do(a) {
        System.out.println("enhance");
        object_.do(a); }public static void main(String[] args) {
        Object_ object_ = new Object_();
        Object_Agent agent = new Object_Agent(object_);
        agent.do();
    }

}
Copy the code

AspectJ static

  • Written in the same way as Spring AOP
  • Rather than generate proxy classes dynamically at run time, Aspectj inserts code into class files at compile time
  • Because it is statically woven, the performance is relatively good

A dynamic proxy

  • JDK dynamic proxies are interface-based in that both the proxy class and the target class implement the same interface.
  • A CGLib dynamic proxy is a proxy class that inherits the target class and then overrides the methods of the target class.

JDK dynamic proxy

interface

public interface Interface_ {
    public void do(a);
}
Copy the code

Classes that need to be strengthened

public class Object_ implements Interface_{
    @Override
    public void do(a) {
        System.out.println("do"); }}Copy the code

Processor implementation class

public class InvocationHandlerImpl implements InvocationHandler{

    private Object object;
    public InvocationHandlerImpl(Object object)
    {
        this.object = object;
    }
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
    {
        System.out.println("enhance");
        Object object = method.invoke(object, args);
        returnobject; }}Copy the code

test

public class DynamicProxyDemonstration
{
    public static void main(String[] args)
    {
        Interface_ object_ = new Object_();
        InvocationHandler handler = new InvocationHandlerImpl(object_);
        ClassLoader loader = object_.getClass().getClassLoader();
        Class[] interfaces = object_.getClass().getInterfaces();
        Interface_ object__ = (Interface_) Proxy.newProxyInstance(loader, interfaces, handler); 
        object__.do();
    }
 
}
Copy the code

CGlib dynamic proxy

POM

<dependency>
        <groupId>cglib</groupId>
        <artifactId>cglib</artifactId>
        <version>2.2.2</version>
</dependency>
Copy the code

Classes that need to be strengthened

public class Object_{
    public  void do(a) {
        System.out.println("do"); }}Copy the code

Method interceptor

public class MyMethodInterceptor implements MethodInterceptor{
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("enhance");
        Object object = proxy.invokeSuper(obj, args);
        returnobject; }}Copy the code

test

public class CgLibProxy {
    public static void main(String[] args) {
        // Create the Enhancer object, a Proxy class similar to JDK dynamic proxies. The next step is to set several parameters
        Enhancer enhancer = new Enhancer();
        // Set the bytecode file of the target class
        enhancer.setSuperclass(Object_.class);
        // Set the callback function
        enhancer.setCallback(new MyMethodInterceptor());
        // Create and run
        Object_ proxyObject_ = (Object_)enhancer.create();
        proxyObject_.do();       
    }
}
Copy the code

Why conversion is CGlib

General writing code:

@Autowired
UserService userService;
Copy the code

Error code:

@Autowired
UserServiceImpl userService;
Copy the code

JDK dynamic proxies are interface-based, and proxies generate objects that can only be assigned to interface variables.

CGLIB doesn’t have that problem. Because CGLIB is implemented by generating subclasses, proxy objects are either assigned to interfaces or implementation classes, both of which are the parent classes of proxy objects.

conclusion

  • Spring5 implements aop as CGlib by default
  • JDK dynamic proxies are interface based, and CGlib dynamic proxies are inheritance based

reference

[1].CGLib dynamic proxy

[2].Java reflection and proxy

[3]. Amazing! Spring5 AOP defaults to Cglib? From phenomenon to source depth analysis

By Both Savage

This paper links: bothsavage. Making. IO / 2020/12/29 /…

Copyright Notice: All articles on this blog are licensed BY-NC-SA unless otherwise stated. Reprint please indicate the source!