国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home Java JavaBase The principle of Java dynamic proxy

The principle of Java dynamic proxy

Nov 29, 2019 pm 05:06 PM
java

The principle of Java dynamic proxy

The emergence of Java dynamic proxy mechanism allows Java developers to dynamically obtain proxy classes without manually writing proxy classes. They can simply specify a set of interfaces and delegate class objects. (Recommended: java video tutorial)

The proxy class will be responsible for dispatching all method calls to the delegate object for reflection execution. During the dispatch execution process, developers can also adjust as needed Delegate class objects and their functions, this is a very flexible and flexible proxy framework. Next we start learning about dynamic agents.

Brief description of dynamic proxy

In the dynamic proxy mechanism of java, there are two important classes or interfaces, one is InvocationHandler( Interface), the other is Proxy (Class).

1. Description of InvocationHandler (interface):

InvocationHandler is the interface implemented by the invocation handler of a proxy instance. 

Each proxy instance has an associated invocation handler. When a method is invoked on a proxy instance, the method invocation is encoded and dispatched to the invoke method of its invocation handler.

Every dynamic proxy class must implement the InvocationHandler interface, and each proxy class instance is associated with When we reach a handler, when we call a method through the proxy object, the call of this method will be forwarded to be called by the invoke method of the InvocationHandler interface. Let’s take a look at the only method of the InvocationHandler interface, the invoke method:

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

This method receives three parameters and returns an Object type. Their respective meanings are as follows:

proxy: refers to The real object we are proxying for

method: refers to the Method object we want to call the method of the real object

args: refers to the parameters received when calling a method of the real object The Object returned by parameter

refers to the return type of the real object method. The above will be understood in depth in the following examples.

the value to return from the method invocation on the proxy instance.

2. Description of Proxy (Class):

Proxy provides static methods for creating dynamic proxy classes and instances, and it is also the superclass of all dynamic proxy classes created by those methods.

The function of Proxy class is to dynamically create a proxy object. We often use the newProxyInstance method:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces,  InvocationHandler h)  throws IllegalArgumentException

Understanding of parameters:

// 一個ClassLoader對象,定義了由哪個ClassLoader對象來對生成的代理對象進行加載
loader - the class loader to define the proxy class  
// 一個Interface對象的數(shù)組,表示的是我將要給我需要代理的對象提供一組什么接口
interfaces - the list of interfaces for the proxy class to implement 
// 一個InvocationHandler對象,表示的是當(dāng)我這個動態(tài)代理對象在調(diào)用方法的時候,會關(guān)聯(lián)到哪一個InvocationHandler對象上
h - the invocation handler to dispatch method invocations to

Understanding of return results: An instance of a proxy object

a proxy instance with the specified invocation handler of a proxy class that is defined by the specified class loader and that implements the specified interfaces

Simple Java proxy

We create a Java project for testing and understanding of dynamic proxy, The project structure is as follows:

The principle of Java dynamic proxy

# 1. First define an interface Interface and add two methods.

package com.huhx.proxy;

public interface Interface {
    void getMyName();

    String getNameById(String id);
}

2. Define a real class that implements the above interface, RealObject:

package com.huhx.proxy;

public class RealObject implements Interface {
    @Override
    public void getMyName() {
        System.out.println("my name is huhx");
    }

    @Override
    public String getNameById(String id) {
        System.out.println("argument id: " + id);
        return "huhx";
    }
}

3. Define a proxy object, which is also implemented The above Interface interface:

package com.huhx.proxy;

public class SimpleProxy implements Interface {
    private Interface proxied;

    public SimpleProxy(Interface proxied) {
        this.proxied = proxied;
    }

    @Override
    public void getMyName() {
        System.out.println("proxy getmyname");
        proxied.getMyName();
    }

    @Override
    public String getNameById(String id) {
        System.out.println("proxy getnamebyid");
        return proxied.getNameById(id);
    }
}

4. SimpleMain In the Main method, test the above results:

package com.huhx.proxy;

public class SimpleMain {
    private static void consume(Interface iface) {
        iface.getMyName();
        String name = iface.getNameById("1");
        System.out.println("name: " + name);
    }

    public static void main(String[] args) {
        consume(new RealObject());
        System.out.println("========================================================");
        consume(new SimpleProxy(new RealObject()));
    }
}

5. The running results are as follows :

my name is huhx
argument id: 1
name: huhx
========================================================
proxy getmyname
my name is huhx
proxy getnamebyid
argument id: 1
name: huhx

Java’s dynamic proxy

After completing the above simple Java proxy, now we start to learn Java’s dynamic proxy, It goes one step further than the idea of ??proxies because it can dynamically create proxies and dynamically handle calls to the proxied methods. All calls made on the dynamic proxy are redirected to a single call handler, whose job is to reveal the type of call and determine the appropriate countermeasure. Below we use cases to deepen our understanding of Java dynamic proxies:

1. Create a processor that inherits InvocationHandler: DynamicProxyHandler

package com.huhx.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.util.Arrays;

public class DynamicProxyHandler implements InvocationHandler {
    private Object proxied;

    public DynamicProxyHandler(Object proxied) {
        System.out.println("dynamic proxy handler constuctor: " + proxied.getClass());
        this.proxied = proxied;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("dynamic proxy name: " + proxy.getClass());
        System.out.println("method: " + method.getName());
        System.out.println("args: " + Arrays.toString(args));
        
        Object invokeObject = method.invoke(proxied, args);
        if (invokeObject != null) {
            System.out.println("invoke object: " + invokeObject.getClass());
        } else {
            System.out.println("invoke object is null");
        }
        return invokeObject;
    }
}

2. We write A test Main method, DynamicProxyMain:

package com.huhx.dynamicproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

import com.huhx.proxy.Interface;
import com.huhx.proxy.RealObject;

public class DynamicProxyMain {
    public static void consumer(Interface iface) {
        iface.getMyName();
        String name = iface.getNameById("1");
        System.out.println("name: " + name);
    }

    public static void main(String[] args) throws Exception, SecurityException, Throwable {
        RealObject realObject = new RealObject();
        consumer(realObject);
        System.out.println("==============================");

        // 動態(tài)代理
        ClassLoader classLoader = Interface.class.getClassLoader();
        Class<?>[] interfaces = new Class[] { Interface.class };
        InvocationHandler handler = new DynamicProxyHandler(realObject);
        Interface proxy = (Interface) Proxy.newProxyInstance(classLoader, interfaces, handler);

        System.out.println("in dynamicproxyMain proxy: " + proxy.getClass());
        consumer(proxy);
    }
}

3. The running results are as follows:

my name is huhx
argument id: 1
name: huhx
==============================
dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
in dynamicproxyMain proxy: class com.sun.proxy.$Proxy0
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getNameById
args: [1]
argument id: 1
invoke object: class java.lang.String
name: huhx

From the above output results, we can draw the following conclusions:

The InvocationHandler associated with the proxy object will execute its invoke method only when the proxy object calls a method.

Understanding of the three parameters of invoke: Object proxy is the object of the proxy, Method method is the Method class that calls the method in the real object, Object[] args is the parameters of the method that is called in the real object

The principle of Java dynamic proxy

1. The key code of dynamic proxy is Proxy.newProxyInstance(classLoader, interfaces, handler). Let’s follow the source code and take a look:

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException {
  // handler不能為空
    if (h == null) {
        throw new NullPointerException();
    }

    final Class<?>[] intfs = interfaces.clone();
    final SecurityManager sm = System.getSecurityManager();
    if (sm != null) {
        checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
    }

    /*
     * Look up or generate the designated proxy class.
     */
  // 通過loader和接口,得到代理的Class對象
    Class<?> cl = getProxyClass0(loader, intfs);

    /*
     * Invoke its constructor with the designated invocation handler.
     */
    try {
        final Constructor<?> cons = cl.getConstructor(constructorParams);
        final InvocationHandler ih = h;
        if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) {
            // create proxy instance with doPrivilege as the proxy class may
            // implement non-public interfaces that requires a special permission
            return AccessController.doPrivileged(new PrivilegedAction<Object>() {
                public Object run() {
                    return newInstance(cons, ih);
                }
            });
        } else {
       // 創(chuàng)建代理對象的實例
            return newInstance(cons, ih);
        }
    } catch (NoSuchMethodException e) {
        throw new InternalError(e.toString());
    }
}

2. Let’s take a look Source code of newInstance method:

private static Object newInstance(Constructor<?> cons, InvocationHandler h) {
    try {
        return cons.newInstance(new Object[] {h} );
    } catch (IllegalAccessException | InstantiationException e) {
        throw new InternalError(e.toString());
    } catch (InvocationTargetException e) {
        Throwable t = e.getCause();
        if (t instanceof RuntimeException) {
            throw (RuntimeException) t;
        } else {
            throw new InternalError(t.toString());
        }
    }
}

3. When we call a method through the proxy object, the call of this method will be forwarded to the invoke method of the InvocationHandler interface. transfer.

I couldn’t find the code that reflected this sentence in the source code, so I added the following code to the main method of the test class:

if (proxy instanceof Proxy) {
    InvocationHandler invocationHandler = Proxy.getInvocationHandler(proxy);
    invocationHandler.invoke(proxy, realObject.getClass().getMethod("getMyName"), null);
    System.out.println("--------------------------------------");
}

這段代碼的輸出結(jié)果如下,與上述中調(diào)用代理對象中的getMyName方法輸出是一樣的,不知道Jvm底層是否是這樣判斷的:

dynamic proxy handler constuctor: class com.huhx.proxy.RealObject
dynamic proxy name: class com.sun.proxy.$Proxy0
method: getMyName
args: null
my name is huhx
invoke object is null
--------------------------------------

更多java知識請關(guān)注java基礎(chǔ)教程欄目。

The above is the detailed content of The principle of Java dynamic proxy. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Go for Scientific Computing and Numerical Analysis Go for Scientific Computing and Numerical Analysis Jul 23, 2025 am 01:53 AM

Go language can be used for scientific calculations and numerical analysis, but it needs to be understood. The advantage lies in concurrency support and performance, which is suitable for parallel algorithms such as distributed solution, Monte Carlo simulation, etc.; community libraries such as gonum and mat64 provide basic numerical calculation functions; hybrid programming can be used to call C/C and Python through Cgo or interface to improve practicality. The limitation is that the ecosystem is not as mature as Python, the visualization and advanced tools are weaker, and some library documents are incomplete. It is recommended to select appropriate scenarios based on Go features and refer to source code examples to use them in depth.

Implementing Event-Driven Architecture with Java and Apache Kafka Implementing Event-Driven Architecture with Java and Apache Kafka Jul 23, 2025 am 03:51 AM

Understand core components: Producers publish events to Topics, Consumers subscribe and process events, KafkaBroker manages message storage and delivery; 2. Locally build Kafka: Use Docker to quickly start ZooKeeper and Kafka services, expose port 9092; 3. Java integration Kafka: introduce kafka-clients dependencies, or use SpringKafka to improve development efficiency; 4. Write Producer: configure KafkaProducer to send JSON format order events to orders topic; 5. Write Consumer: Subscribe to o through KafkaConsumer

Angular Material and Component Libraries Angular Material and Component Libraries Jul 23, 2025 am 01:17 AM

How to get started with AngularMaterial? First run ngadd@angular/material to install and configure, secondly, introduce components such as MatButtonModule as needed, then import and use components in the module, and finally add global styles and fonts; the advantages of AngularMaterial include a unified design language, rich components, good documentation and community support, and strong customization; other alternatives include NG-ZORRO, PrimeNG, ClarityDesign and IonicforAngular, and when choosing, you should consider comprehensively based on project needs and team familiarity.

Frontend Build Time Optimization Frontend Build Time Optimization Jul 23, 2025 am 03:37 AM

The core of optimizing front-end build time is to reduce redundant work, improve processing efficiency, utilize caches and select efficient tools. 1. Use TreeShaking and code segmentation reasonably to ensure that it is introduced on demand and dynamic import reduces the packaging volume; 2. Reduce unnecessary loader processing, exclude node_modules, upgrade loaders and relax the scope of Babel translation; 3. Use the caching mechanism to speed up repeated construction, enable Webpack cache, CI cache and use offline installation; 4. Upgrade toolchain, such as using Vite, esbuild or Rollup to improve the construction speed, although there is migration cost, it has significant effect.

Java Native Memory Diagnostics and Tools Java Native Memory Diagnostics and Tools Jul 23, 2025 am 12:09 AM

Confirm that the NativeMemory problem is manifested as normal heap memory but the total process memory is growing, the RES memory is far beyond the -Xmx setting, and an OOM error of Directbuffer or nativethread. 1. Use NMT (-XX:NativeMemoryTracking=summary) to track the native memory of JVM and view the memory trends of modules such as Thread and Internal through jcmd; 2. Pay attention to the DirectBuffer leakage, it is not released when using allocateDirect() or the MaxDirectMemorySize setting is unreasonable; 3. Check that too many threads lead to high stack space occupancy, which can be used

How the Java `equals()` and `hashCode()` Methods Work How the Java `equals()` and `hashCode()` Methods Work Jul 23, 2025 am 02:02 AM

The equals() and hashCode() methods must be rewrite correctly at the same time, otherwise the hash set (such as HashMap and HashSet) will be invalid; 2. Equals() is used to define the logical equality of objects, and the actual field values need to be compared instead of references; 3. HashCode() returns the object hash code, and it is necessary to ensure that the equal objects have the same hash value; 4. Violating the contract will make it impossible to find the stored object from the collection, because hash search first uses hashCode() to locate the bucket, and then uses equals() to confirm the match; 5. It is recommended to use Objects.equals() and Objects.hash() to implement null safe and consistent logic, and avoid objects used as keys.

Surviving the Java Coding Interview: Data Structures and Algorithms Surviving the Java Coding Interview: Data Structures and Algorithms Jul 23, 2025 am 03:46 AM

Master the core data structure and its applicable scenarios, such as the selection of HashMap and TreeMap, and the expansion mechanism of ArrayList; 2. Practice algorithms from the Java perspective, proficient in double pointer, sliding window, DFS/BFS and other modes and can be clearly implemented; 3. Write clean and robust Java code, pay attention to naming, boundary processing and language features (such as generics and final); 4. Prepare the practical question of "why use Java" and understand the impact of StringBuilder, GC, etc. on performance; maintain practice and clear expression to stand out.

Java Security for SQL Injection Prevention Java Security for SQL Injection Prevention Jul 22, 2025 am 03:56 AM

The core methods to prevent SQL injection include: 1. Use PreparedStatement precompiled statements to ensure that the input is processed as data; 2. Whitelist verification, length limit and special character escape of the input; 3. Correctly use ORM frameworks such as Hibernate and MyBatis to avoid splicing SQL; 4. Do not expose error information, scan for vulnerabilities regularly, and restrict database permissions. These measures jointly ensure the SQL security of Java applications.

See all articles