प्रोग्रामिक रूप से स्प्रिंग बूट एप्लिकेशन बंद करें


109

कैसे कर सकते हैं मैं प्रोग्राम के रूप में बंद एक स्प्रिंग बूट आवेदन वीएम समाप्त बिना ?

अन्य कार्यों में, इसके विपरीत क्या है

new SpringApplication(Main.class).run(args);

1
अच्छी बात! उस पर बंद () को बुलाकर काम करना चाहिए।
एक्सल फोंटेन


@AnandVarkeyPhilips नहीं, यह निश्चित रूप से नहीं है। यह एक एपीआई के बारे में है, दूसरा ऐसा करने के लिए एक तरीका है।
एक्सल फोंटेन

ठीक है .. यह प्रश्न लिंक दूसरों की मदद कर सकता है। क्या आप चाहते हैं कि मैं उपरोक्त टिप्पणी को हटा दूं?
आनंद वर्की फिलिप्स

जवाबों:


111

एक समापन SpringApplicationमूल रूप से अंतर्निहित बंद करने का मतलब है ApplicationContextSpringApplication#run(String...)विधि आपको यह बताती है कि ApplicationContextConfigurableApplicationContext। फिर close()आप स्वयं कर सकते हैं ।

उदाहरण के लिए,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to shut down...
        ctx.close();
    }
}

वैकल्पिक रूप से, आप इसे करने के लिए static SpringApplication.exit(ApplicationContext, ExitCodeGenerator...)सहायक विधि का उपयोग कर सकते हैं । उदाहरण के लिए,

@SpringBootApplication
public class Example {
    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = SpringApplication.run(Example.class, args);
        // ...determine it's time to stop...
        int exitCode = SpringApplication.exit(ctx, new ExitCodeGenerator() {
            @Override
            public int getExitCode() {
                // no errors
                return 0;
            }
        });

        // or shortened to
        // int exitCode = SpringApplication.exit(ctx, () -> 0);

        System.exit(exitCode);
    }
}

1
अगर मैं ctx.close () का उपयोग करता हूं; सही पर System.exit (n) को कॉल करने की कोई आवश्यकता नहीं है? संदर्भ बंद () के अंदर System.exit () होना चाहिए?
डेनिस

2
@Denys नहीं, संदर्भ बंद होने पर जावा प्रक्रिया से बाहर नहीं निकलता है। मेरे उदाहरण में बाहर निकलना दर्शाता है कि ExitCodeGeneratorइसका उपयोग कैसे किया जा सकता है। आप केवल mainकृपापूर्वक बाहर निकलने की विधि से वापस आ सकते हैं (कोड 0 से बाहर निकलें)।
सोतिरियोस डेलिमोलिस

78

स्प्रिंग बूट एप्लिकेशन में आप कुछ इस तरह का उपयोग कर सकते हैं

ShutdownManager.java

import org.springframework.context.ApplicationContext;
import org.springframework.boot.SpringApplication;

@Component
class ShutdownManager{

    @Autowired
    private ApplicationContext appContext;

    public void initiateShutdown(int returnCode){
        SpringApplication.exit(appContext, () -> returnCode);
    }
}

16
यह दर्शाने के लिए कि ApplicationContextस्वचालित रूप से अन्य फलियों में इंजेक्ट किया जा सकता है।
एंथनी चुइनार्ड

1
@snovelli आरंभ शटडाउन विधि कैसे शुरू करें? आरंभ (एक्स), एक्स = ०?
स्टैकऑवरफ्लो

जब सशर्त बंद होता है, तो इसे निष्पादित किया जा सकता है। SpringApplication.run (..)। करीब () कार्यक्रम पूरा होने के रूप में करेंगे।
अबूबकर सिद्दीक

क्यों SpringApplication? (appContext, () -> returnCode); क्यों नहीं कर सकते AppContext.close ()। अंतर क्या है ?
रैम्स

@StackOverFlow आपको बीन को इंजेक्ट करने की आवश्यकता है जहां आपको इसकी आवश्यकता है और यदि आपने सही तरीके से बंद कर दिया है तो रिटर्न कोड को पास करें (x = 0)। उदाहरण के लिए, आप शटडाउन प्रबंधक को एक रेस्टकंट्रोलर में इंजेक्ट कर सकते हैं और रिमोट शटडाउन की अनुमति दे सकते हैं, या आप इसे एक हेल्थकेयर मॉनिटरिंग में इंजेक्ट कर सकते हैं जो जेवीएम को नीचे की ओर लापता सेवाओं के मामले में बंद कर देगा
स्नोवेल्ली

36

यह काम करता है, यहां तक ​​कि मुद्रित भी किया जाता है।

  SpringApplication.run(MyApplication.class, args).close();
  System.out.println("done");

इसलिए .close()बाद में जोड़नाrun()

स्पष्टीकरण:

public ConfigurableApplicationContext run(String... args)

एक नया ApplicationContext बनाने और ताज़ा करने के लिए, स्प्रिंग एप्लिकेशन चलाएँ। पैरामीटर:

args - आवेदन तर्क (आमतौर पर जावा मुख्य विधि से पारित)

रिटर्न: एक चल रहा ApplicationContext

तथा:

void close()इस एप्लिकेशन के संदर्भ को बंद करें, जो सभी संसाधनों और तालों को जारी करता है जो कार्यान्वयन को रोक सकता है। इसमें सभी कैश्ड सिंगलटन बीन्स को नष्ट करना शामिल है। नोट: एक मूल संदर्भ के करीब आह्वान नहीं करता है; माता-पिता संदर्भों का अपना, स्वतंत्र जीवनचक्र है।

इस विधि को साइड इफेक्ट्स के बिना कई बार कहा जा सकता है: पहले से ही बंद संदर्भ पर निकटवर्ती कॉल को अनदेखा किया जाएगा।

इसलिए मूल रूप से, यह मूल संदर्भ को बंद नहीं करेगा, यही कारण है कि VM नहीं छोड़ता है।


2
बस यह उपाय बैच की तरह अल्पकालिक प्रक्रिया के लिए काम करता है, लेकिन स्प्रिंग एमवीसी अनुप्रयोगों पर इसका उपयोग न करें। आवेदन केवल बूटिंग के बाद बंद हो जाता है।
माइकल COLL

@MichaelCOLL इस सवाल के बारे में है कि प्रकार की परवाह किए बिना एक स्प्रिंग बूट ऐप को प्रोग्रामेटिक रूप से कैसे बंद किया जाए। यह
एसीवी

1
@ACV आप सही हैं यह काम करता है, यह बहुत अच्छी तरह से काम करता है। लेकिन एक ऐप के लिए जिसे रहना चाहिए (जैसे स्प्रिंग एमवीसी ऐप), मुझे लगता है, यह ऐसा करने का अच्छा तरीका नहीं है। मेरे मामले में, मैंने उपयोग किया है SpringApplication.exit(appContext, () -> returnCode)
माइकल COLL

1
आप अपनी अंतिम पंक्ति में किस वीएम का उल्लेख कर रहे हैं? यदि आप अपना स्प्रिंग बूट एप्लिकेशन शुरू कर रहे हैं SpringApplication.run(MyApplication.class, args), तो इसका कोई मूल संदर्भ नहीं है। केवल एक संदर्भ है, संदर्भ बनाया और runउसके द्वारा लौटाया गया , जिसे आप फिर तुरंत close। @ मिचेल सही है। यह उन कार्यक्रमों के लिए काम नहीं करेगा जिन्हें स्प्रिंग संदर्भ के आरंभ होने के बाद कुछ भी करने की आवश्यकता है, जो कि अधिकांश कार्यक्रम हैं।
उद्धारकर्ता

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

3

आवेदन में आप उपयोग कर सकते हैं SpringApplication। इसमें एक स्थिर exit()विधि है जो दो तर्क लेती है: a ApplicationContextऔर a ExitCodeGenerator:

अर्थात आप इस विधि की घोषणा कर सकते हैं:

@Autowired
public void shutDown(ExecutorServiceExitCodeGenerator exitCodeGenerator) {
    SpringApplication.exit(applicationContext, exitCodeGenerator);
}

एकीकरण परीक्षणों के अंदर आप इसे @DirtiesContextकक्षा स्तर पर एनोटेशन जोड़कर प्राप्त कर सकते हैं :

  • @DirtiesContext(classMode=ClassMode.AFTER_CLASS) - संबंधित ApplicationContext को टेस्ट क्लास के बाद गंदे के रूप में चिह्नित किया जाएगा।
  • @DirtiesContext(classMode=ClassMode.AFTER_EACH_TEST_METHOD) - संबंधित ApplicationContext को कक्षा में प्रत्येक परीक्षण विधि के बाद गंदे के रूप में चिह्नित किया जाएगा।

अर्थात

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = {Application.class},
    webEnvironment= SpringBootTest.WebEnvironment.DEFINED_PORT, properties = {"server.port:0"})
@DirtiesContext(classMode= DirtiesContext.ClassMode.AFTER_CLASS)
public class ApplicationIT {
...

ठीक। मैं ExecutorServiceExitCodeGenerator कहाँ प्राप्त करने वाला हूँ? यदि यह बीन है, तो क्या आप सृजन स्निपेट कोड दिखा सकते हैं (और यह किस वर्ग से बनाया गया है)? किस कक्षा में विधि शटडाउन (ExecutorServiceExitCodeGenerator exitCodeGenerator) डालनी चाहिए?
व्लाड जी।

2

इससे यह सुनिश्चित हो जाएगा कि स्प्रिंगबूट एप्लिकेशन ठीक से बंद हो गया है और संसाधन ऑपरेटिंग सिस्टम में वापस आ गए हैं,

@Autowired
private ApplicationContext context;

@GetMapping("/shutdown-app")
public void shutdownApp() {

    int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);
    System.exit(exitCode);
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.