Spring Boot 4 की संपूर्ण मार्गदर्शिका · पाठ

रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत

रिफ्लेक्शन, प्रॉक्सी और संसाधन संकेत पंजीकृत कीजिए, ताकि नेटिव संकलन के बाद भी गतिशील सुविधाएँ काम करती रहें।

पाठ 2, कुल 4 में से13 चरण

रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत, CoddyKit पर Spring Boot 4 की संपूर्ण मार्गदर्शिका का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Spring Boot 4 की संपूर्ण मार्गदर्शिका सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

नेटिव इमेज रिफ्लेक्शन को क्यों तोड़ती हैं

GraalVM नेटिव कंपाइलेशन बंद-विश्व विश्लेषण का उपयोग करता है: बिल्ड समय पर उसे हर उस क्लास, विधि और फ़ील्ड को देखना आवश्यक है, जिस तक कभी भी पहुँचा जा सकता है। जिन कोड पथों की पहुँच-योग्यता को वह स्थिर रूप से सिद्ध नहीं कर सकता, उन्हें अंतिम बाइनरी से हटा दिया जाता है।

  • रिफ्लेक्शन (Class.forName, getDeclaredMethod) लक्ष्य को स्थिर विश्लेषण से छिपा देता है।
  • रनटाइम पर बनाए गए डायनेमिक प्रॉक्सी की ऐसी कोई क्लास नहीं होती जिसे बिल्ड समय पर स्कैन किया जा सके।
  • getResourceAsStream के ज़रिए लोड किए गए संसाधन तब तक शामिल नहीं किए जाते, जब तक उन्हें घोषित न किया जाए।

समाधान यह है कि विश्लेषक को रनटाइम संकेत नामक स्पष्ट मेटाडेटा दिया जाए, ताकि वह इन तत्वों को इमेज में बनाए रखे।

Spring Boot स्वचालित रूप से क्या जोड़ता है

Spring Boot 4 और AOT (पहले से) इंजन अधिकांश फ़्रेमवर्क आंतरिक घटकों के लिए पहले से ही संकेत पंजीकृत करते हैं: @Component beans, @ConfigurationProperties क्लासें, controllers के ज़रिए पहुँचे Jackson-बाउंड DTO और ऑटो-कॉन्फ़िगरेशन क्लासें।

आपको अपने संकेत केवल तब लिखने होते हैं, जब आप ऐसा कुछ करते हैं जिसे AOT इंजन ट्रेस नहीं कर सकता, जैसे:

  • कॉन्फ़िगरेशन से नाम द्वारा लोड की गई क्लास का रिफ्लेक्शन से इंस्टैंशिएशन करना।
  • ऐसे प्रकार को सीरियलाइज़ करना जिसका कोई controller या रिपॉज़िटरी संदर्भ नहीं देती।
  • रनटाइम पर ऐसी संसाधन फ़ाइल पढ़ना जिसे क्लासपाथ स्कैनिंग से नहीं खोजा जाता।
  • अपने बनाए हुए इंटरफ़ेस के लिए JDK डायनेमिक प्रॉक्सी बनाना।

RuntimeHintsRegistrar इंटरफ़ेस

प्रोग्राम के माध्यम से प्रवेश का मुख्य बिंदु RuntimeHintsRegistrar है। आप एकल विधि registerHints लागू करते हैं, जिसे एक RuntimeHints ऑब्जेक्ट मिलता है। यह ऑब्जेक्ट प्रतिबिंब, संसाधनों, प्रॉक्सी, क्रमांकन और संसाधन बंडलों के लिए उप-पंजीकरण उपलब्ध कराता है।

ClassLoader पैरामीटर आपको केवल तब सशर्त रूप से पंजीकरण करने देता है, जब कोई प्रकार वास्तव में क्लासपाथ पर मौजूद हो।

package com.example.demo.hints;

import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

public class MyRuntimeHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        // reflection, resources and proxies are registered here
    }
}

प्रतिबिंब संकेत पंजीकृत करना

hints.reflection().registerType(...) का उपयोग करें और आवश्यक सदस्य श्रेणियाँ पास करें। श्रेणियाँ व्यापक स्तर के स्विच हैं, जो GraalVM को बताती हैं कि किन सदस्यों को प्रतिबिंब के माध्यम से सुलभ बनाए रखना है।

  • INVOKE_DECLARED_CONSTRUCTORS — कंस्ट्रक्टरों को कॉल करने योग्य बनाए रखें।
  • INVOKE_DECLARED_METHODS — विधियों को कॉल करने योग्य बनाए रखें।
  • DECLARED_FIELDS — फ़ील्ड को पढ़ने और लिखने योग्य बनाए रखें।

केवल वही अनुमति दें जिसका आप वास्तव में उपयोग करते हैं; बहुत व्यापक संकेत इमेज का आकार बढ़ा देते हैं।

import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

public class ReflectionHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        hints.reflection().registerType(
            com.example.demo.PaymentProcessor.class,
            MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
            MemberCategory.INVOKE_DECLARED_METHODS);
    }
}

@ImportRuntimeHints से संकेत सक्रिय करना

जब तक Spring को उसे चलाने के लिए नहीं कहा जाता, कोई पंजीकरणकर्ता कुछ नहीं करता। किसी भी कॉन्फ़िगरेशन या घटक क्लास पर @ImportRuntimeHints एनोटेशन लगाकर उसमें अपने पंजीकरणकर्ता का संदर्भ दें। इसके बाद AOT इंजन बिल्ड के दौरान उसे कॉल करता है।

इसे उस कोड के पास रखें जिसे इस संकेत की आवश्यकता है, ताकि दोनों के बीच का संबंध आसानी से समझ में आए।

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportRuntimeHints;

@Configuration
@ImportRuntimeHints(ReflectionHints.class)
public class PaymentConfig {
    // beans that rely on reflective access to PaymentProcessor
}

TypeReference के साथ सशर्त पंजीकरण

यदि बिल्ड के समय कोई क्लास अनुपस्थित हो सकती है, तो स्पष्ट .class लिटरल के बजाय TypeReference का उपयोग करके उसे नाम से पंजीकृत करें। इसे उपस्थिति जाँच के साथ मिलाएँ, ताकि संकेत केवल तब जोड़ा जाए जब प्रकार क्लासपाथ पर मौजूद हो।

यह तरीका उन स्टार्टर लाइब्रेरी में सामान्य है जो वैकल्पिक निर्भरताओं के अनुसार अपना व्यवहार बदलती हैं।

import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;
import org.springframework.util.ClassUtils;

public class OptionalHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        if (ClassUtils.isPresent("com.example.optional.LegacyAdapter", classLoader)) {
            hints.reflection().registerType(
                TypeReference.of("com.example.optional.LegacyAdapter"),
                MemberCategory.INVOKE_DECLARED_CONSTRUCTORS);
        }
    }
}

संसाधन संकेत पंजीकृत करना

getResourceAsStream या ClassPathResource से लोड की जाने वाली फ़ाइलों को घोषित करना आवश्यक है, वरना वे नेटिव बाइनरी से गायब हो जाती हैं। hints.resources() के माध्यम से सटीक पथ या ग्लोब-शैली के पैटर्न पंजीकृत करें।

  • registerPattern("config/*.json") — मेल खाने वाले क्लासपाथ संसाधनों को शामिल करें।
  • registerResource(...) — किसी एक ज्ञात Resource को शामिल करें।
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

public class ResourceHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        hints.resources()
             .registerPattern("templates/email/*.html")
             .registerPattern("data/countries.json");
    }
}

प्रॉक्सी संकेत पंजीकृत करना

Proxy.newProxyInstance से बनाए गए JDK डायनेमिक प्रॉक्सी में लागू किए गए प्रत्येक इंटरफ़ेस को घोषित करना आवश्यक है, क्योंकि GraalVM को बिल्ड के समय प्रॉक्सी क्लास बनानी होती है। सभी इंटरफ़ेस के साथ hints.proxies().registerJdkProxy(...) का उपयोग करें।

Spring अपने @Transactional और रिपॉज़िटरी इंटरफ़ेस के लिए प्रॉक्सी स्वतः पंजीकृत करता है; आपको केवल स्वयं बनाए गए प्रॉक्सी के लिए संकेत जोड़ने होते हैं।

import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;

public class ProxyHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        hints.proxies().registerJdkProxy(
            com.example.demo.AuditLog.class,
            com.example.demo.Versioned.class);
    }
}

बहु-श्रेणी पंजीकरणकर्ता का पूरा उदाहरण

वास्तविक पंजीकरणकर्ता आम तौर पर कई प्रकार के संकेतों को मिलाते हैं। यहाँ एक ही पंजीकरणकर्ता गतिशील रूप से लोड की गई रणनीति के लिए प्रतिबिंब, उसके कॉन्फ़िगरेशन के लिए संसाधन पैटर्न और उस इंटरफ़ेस के लिए प्रॉक्सी घोषित करता है जिसे ऐप रनटाइम पर जोड़ता है।

संबंधित संकेतों को साथ रखने से यह स्पष्ट रूप से दर्ज होता है कि कोई सुविधा किन गतिशील क्षमताओं पर निर्भर करती है।

import org.springframework.aot.hint.MemberCategory;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.RuntimeHintsRegistrar;
import org.springframework.aot.hint.TypeReference;

public class StrategyHints implements RuntimeHintsRegistrar {

    @Override
    public void registerHints(RuntimeHints hints, ClassLoader classLoader) {
        hints.reflection().registerType(
            TypeReference.of("com.example.demo.JsonExportStrategy"),
            MemberCategory.INVOKE_DECLARED_CONSTRUCTORS,
            MemberCategory.INVOKE_DECLARED_METHODS);

        hints.resources().registerPattern("strategies/*.properties");

        hints.proxies().registerJdkProxy(
            com.example.demo.ExportStrategy.class);
    }
}

@RegisterReflectionForBinding से क्रमांकन के लिए संकेत देना

उन DTO के लिए जिन तक केवल प्रतिबिंब के माध्यम से पहुँचा जाता है—उदाहरण के लिए, किसी भी नियंत्रक के बाहर हाथ से बनाए गए ObjectMapper के माध्यम से—सुविधाजनक एनोटेशन @RegisterReflectionForBinding Jackson बाइंडिंग के लिए आवश्यक सभी सदस्यों को एक ही पंक्ति में पंजीकृत कर देता है और श्रेणियों को हाथ से सूचीबद्ध करने की आवश्यकता समाप्त करता है।

यह एक संक्षिप्त तरीका है, जो अंदर से उसी प्रतिबिंब पंजीकरण को सौंप देता है।

import org.springframework.aot.hint.annotation.RegisterReflectionForBinding;
import org.springframework.stereotype.Component;

@Component
@RegisterReflectionForBinding({ InvoiceDto.class, LineItemDto.class })
public class InvoiceExporter {
    // serializes InvoiceDto with a hand-built ObjectMapper
}

नेटिव बनाने से पहले संकेतों की जाँच करना

नेटिव इमेज संकलित करना धीमा होता है, इसलिए पहले JVM पर संकेतों की जाँच करें। GraalVM reachability metadata agent सामान्य परीक्षण चलने के दौरान वास्तविक प्रतिबिंब और संसाधन पहुँच को दर्ज करता है और JSON मेटाडेटा बनाता है, जिसकी तुलना आप अपने संकेतों से कर सकते हैं।

Spring RuntimeHintsPredicates भी उपलब्ध कराता है, जिससे यूनिट परीक्षण में यह सुनिश्चित किया जा सकता है कि कोई दिया गया प्रकार या संसाधन पंजीकृत है—पूरी नेटिव बिल्ड के बिना तेज़ प्रतिक्रिया मिलती है।

import org.junit.jupiter.api.Test;
import org.springframework.aot.hint.RuntimeHints;
import org.springframework.aot.hint.predicate.RuntimeHintsPredicates;
import static org.assertj.core.api.Assertions.assertThat;

class ReflectionHintsTest {

    @Test
    void registersPaymentProcessor() {
        RuntimeHints hints = new RuntimeHints();
        new ReflectionHints().registerHints(hints, getClass().getClassLoader());

        assertThat(RuntimeHintsPredicates.reflection()
                .onType(com.example.demo.PaymentProcessor.class))
            .accepts(hints);
    }
}

त्वरित जाँच: प्रॉक्सी संकेत

आपका ऐप Proxy.newProxyInstance का उपयोग करके अपने दो इंटरफ़ेस के लिए JDK डायनेमिक प्रॉक्सी बनाता है। यह JVM पर काम करता है, लेकिन नेटिव इमेज में रनटाइम पर त्रुटि उत्पन्न करता है। इसे ठीक करने वाला संकेत कौन-सा है?

पुनरावलोकन

GraalVM का बंद-विश्व विश्लेषण ऐसी हर चीज़ को हटा देता है जिसकी पहुँच स्थिर रूप से सिद्ध नहीं की जा सकती, इसलिए गतिशील सुविधाओं के लिए स्पष्ट रनटाइम संकेत आवश्यक हैं।

  • RuntimeHintsRegistrar.registerHints लागू करें और उसे @ImportRuntimeHints से सक्रिय करें।
  • सही MemberCategory मानों के साथ hints.reflection().registerType(...) का उपयोग करने पर प्रतिबिंब वाले कंस्ट्रक्टर, विधियाँ और फ़ील्ड सुरक्षित रहते हैं।
  • hints.resources().registerPattern(...) रनटाइम पर लोड की जाने वाली फ़ाइलों को बंडल करता है।
  • hints.proxies().registerJdkProxy(...) कस्टम JDK डायनेमिक प्रॉक्सी घोषित करता है।
  • @RegisterReflectionForBinding क्रमांकन वाले DTO के लिए संक्षिप्त तरीका है।
  • महँगी नेटिव बिल्ड से पहले RuntimeHintsPredicates और reachability metadata agent से जाँच करें।
शुरुआत निःशुल्क

एआई शिक्षक के साथ Java सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
21
पाठ
84

अक्सर पूछे जाने वाले प्रश्न

क्या “रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत” पाठ निःशुल्क है?

हाँ — Spring Boot 4 की संपूर्ण मार्गदर्शिका अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत” में मैं क्या सीखूँगा?

रिफ्लेक्शन, प्रॉक्सी और संसाधन संकेत पंजीकृत कीजिए, ताकि नेटिव संकलन के बाद भी गतिशील सुविधाएँ काम करती रहें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Spring Boot 4 की संपूर्ण मार्गदर्शिका का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Spring Boot 4 की संपूर्ण मार्गदर्शिका शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Spring Boot 4 की संपूर्ण मार्गदर्शिका शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Spring Boot 4 की संपूर्ण मार्गदर्शिका पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. AOT प्रोसेसिंग और नेटिव बिल्ड पाइपलाइन
  2. रिफ्लेक्शन और संसाधनों के लिए रनटाइम संकेत
  3. क्लास डेटा साझाकरण और JVM स्टार्टअप ट्यूनिंग
  4. नेटिव संगतता समस्याओं का निदान और समाधान
← Spring Boot 4 की संपूर्ण मार्गदर्शिका पर वापस जाएँ