স্প্রিং বুট শুরু হওয়ার পরে চলমান কোড


211

আমার বসন্ত-বুট অ্যাপ্লিকেশন পরিবর্তনের জন্য কোনও ডিরেক্টরি নিরীক্ষণ শুরু করার পরে আমি কোড চালাতে চাই ।

আমি একটি নতুন থ্রেড চালানোর চেষ্টা করেছি তবে @Autowiredপরিষেবাগুলি সেই মুহূর্তে সেট করা হয়নি।

আমি সন্ধান করতে সক্ষম হয়েছি ApplicationPreparedEvent, @Autowiredটীকাগুলি সেট করার আগে কোনটি আগুন লাগায় । অ্যাপ্লিকেশনটি http অনুরোধগুলি প্রক্রিয়া করার জন্য প্রস্তুত হয়ে গেলে আমি আদর্শভাবেই ইভেন্টটি ছড়িয়ে দিতে চাই।

স্প্রিং-বুটে অ্যাপ্লিকেশন লাইভ হওয়ার পরে কি আরও ভাল কোনও ইভেন্ট ব্যবহার করার, বা কোড চালানোর আরও ভাল উপায় আছে ?



স্প্রিং বুট দুটি ইন্টারফেস সরবরাহ করে অ্যাপ্লিকেশন রুনার এবং কমান্ডলাইনরুনার যা আপনি যখন বসন্ত বুট শুরু হওয়ার পরে কোড চালাতে চান তখন ব্যবহার করা যেতে পারে। আপনি বাস্তবায়ন উদাহরণের জন্য এই নিবন্ধটি উল্লেখ করতে পারেন - jhooq.com/applicationrunner-spring-boot
রাহুল ওয়াঘ

উত্তর:


121

চেষ্টা করুন:

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application extends SpringBootServletInitializer {

    @SuppressWarnings("resource")
    public static void main(final String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(Application.class, args);

        context.getBean(Table.class).fillWithTestdata(); // <-- here
    }
}

6
আপনি যখন বাহ্যিক টমক্যাটে যুদ্ধ ফাইল হিসাবে অ্যাপ্লিকেশন স্থাপন করবেন তখন এটি কাজ করে না। এটি কেবল এম্বেডড টমক্যাট দিয়েই কাজ করে
সৌরভ

না, এটি কাজ করে না। তবে এই ব্যবহারের ক্ষেত্রে আমি এর পরিবর্তে আরও সুস্পষ্ট উপায় পছন্দ করি @Component। যুদ্ধের ফাইলে কাজ করার জন্য @ সিজেস্টেহনোর উত্তর দেখুন।
আন্তন বেসনভ

320

এটি এর মতোই সহজ:

@EventListener(ApplicationReadyEvent.class)
public void doSomethingAfterStartup() {
    System.out.println("hello world, I have just started up");
}

সংস্করণে পরীক্ষিত 1.5.1.RELEASE


7
তোমাকে ধন্যবাদ. এটি কোনও পরিবর্তন ছাড়াই আমার কোড তৈরি করে। এত সহজ উত্তরের জন্য আবার ধন্যবাদ। এটি কোনও সমস্যা ছাড়াই @RequestMapping টীকাটি নিয়ে কাজ করবে।
হর্ষিত

16
এর @EventListener(ContextRefreshedEvent.class)পরিবর্তে কেউ ব্যবহার করতে ইচ্ছুক হতে পারে যা শিম তৈরির পরে ট্রিগার হয়ে যায় তবে সার্ভারটি শুরু হওয়ার আগেই। কোনও অনুরোধ সার্ভারে আঘাত করার আগে এটি ক্রিয়াকলাপ সম্পাদন করতে ব্যবহৃত হতে পারে।
নীরজ 22'18

3
@ নেররাজ, প্রশ্নটি স্প্রিং বুট শুরু হওয়ার পরে চলমান কোড সম্পর্কে। আপনি যদি ব্যবহার করেন তবে ContextRefreshedEventএটি প্রতিটি রিফ্রেশের পরেও চলবে।
কেহেন

4
স্প্রিং বুট 2.0.5.RELEASE উপর পরীক্ষা
রীতেশ

2
২.২.২ রিলিজ পরীক্ষা করা হয়েছে। এটা পুরোপুরি কাজ করে। এই সমাধানটি আমার সময় সাশ্রয় করে।
Arphile

96

আপনি কি অ্যাপ্লিকেশন রেডিইভেন্ট চেষ্টা করেছেন?

@Component
public class ApplicationStartup 
implements ApplicationListener<ApplicationReadyEvent> {

  /**
   * This event is executed as late as conceivably possible to indicate that 
   * the application is ready to service requests.
   */
  @Override
  public void onApplicationEvent(final ApplicationReadyEvent event) {

    // here your code ...

    return;
  }
}

থেকে কোড: http://blog.netgloo.com/2014/11/13/run-code-at-spring-boot-startup/

এই কি ডকুমেন্টেশন প্রারম্ভে ঘটনা সম্পর্কে উল্লেখ:

...

আপনার অ্যাপ্লিকেশন চলার সাথে সাথে অ্যাপ্লিকেশন ইভেন্টগুলি নিম্নলিখিত ক্রমে প্রেরণ করা হয়েছে:

রান শুরুর সময় একটি অ্যাপ্লিকেশনস্টার্টএভেন্ট প্রেরণ করা হয় তবে শ্রোতাদের এবং ইনিশিয়ালাইজারদের নিবন্ধকরণ বাদে কোনও প্রক্রিয়াজাতকরণের আগেই।

প্রসঙ্গটিতে পরিবেশের জন্য পরিবেশটি ব্যবহার করার কথাটি জানা গেলেও প্রসঙ্গটি তৈরি হওয়ার আগে একটি অ্যাপ্লিকেশন-পরিবেশগত প্রস্তুতিমূলক ইভেন্ট পাঠানো হয়।

রিফ্রেশ শুরু হওয়ার ঠিক আগে একটি অ্যাপ্লিকেশনপ্রিপারডভেন্ট পাঠানো হয় তবে বিনের সংজ্ঞা লোড হওয়ার পরে।

রিফ্রেশের পরে একটি অ্যাপ্লিকেশনলিডিভেন্ট প্রেরণ করা হয় এবং কোনও সম্পর্কিত কলব্যাকগুলি নির্দেশিত করতে প্রক্রিয়া করা হয়েছে যা অ্যাপ্লিকেশনটি পরিষেবার অনুরোধগুলির জন্য প্রস্তুত।

প্রারম্ভকালে কোনও ব্যতিক্রম থাকলে একটি অ্যাপ্লিকেশনবেলড এভেন্ট পাঠানো হয়।

...


11
বিকল্প হিসাবে, আপনি @EventListenerএকটি বিন পদ্ধতিতে টীকাগুলি ব্যবহার করে এটি করতে পারেন, আপনি যে শ্রেণীর ইভেন্টটি করতে চান সেটিকে তর্ক হিসাবে।
প্যাডিলো

2
এটি নির্বাচিত উত্তর হওয়া উচিত।
varun113

2
এটি বসন্ত-বুট ২-এ পরিবর্তিত হয়েছে যদি আপনি যদি ১.x থেকে পোর্ট আপ করে থাকেন এবং অ্যাপ্লিকেশনস্টার্টইভেন্ট ব্যবহার করে থাকেন তবে তার পরিবর্তে আপনি এখন অ্যাপ্লিকেশন স্টার্টিংএভেন্ট চান।
অ্যান্ডি ব্রাউন

এটি একেবারে সূক্ষ্মভাবে কাজ করে এবং আমি মনে করি এটি করার সেরা উপায়।
অবিনাশ শ্রিমালি

আপনি সেরা
সেপ্টেম্বর

83

আপনার মনিটরটি আরম্ভ করার সময় কেবল এমন শিম তৈরি করবেন না কেন এমন কিছু:

@Component
public class Monitor {
    @Autowired private SomeService service

    @PostConstruct
    public void init(){
        // start your monitoring in here
    }
}

initযতক্ষণ না কোনো autowiring শিম জন্য সম্পন্ন করা হয় পদ্ধতি নামক করা হবে না।


14
কখনও কখনও @PostConstructখুব তাড়াতাড়ি আগুন লাগে। উদাহরণস্বরূপ, স্প্রিং ক্লাউড স্ট্রিম কাফকা ব্যবহার করার সময়, @PostConstructঅ্যাপ্লিকেশন কাফকার সাথে আবদ্ধ হওয়ার আগে আগুন জ্বলে। ডেভ সিয়ারের সমাধানটি আরও ভাল কারণ এটি সময়মতো আগুন দেয়।
এলনুর আব্দুররাখিমভ

9
@PostConstructআরম্ভের সময় ঘটে, পরে হয় না। যদিও এটি কিছু ক্ষেত্রে কার্যকর হতে পারে তবে আপনি যদি স্প্রিং বুট শুরুর পরে চালাতে চান তবে এটি সঠিক উত্তর নয় । উদাহরণস্বরূপ, @PostConstructশেষ না করা অবস্থায় শেষ পয়েন্টগুলির কোনওটিই উপলভ্য নয়।
কেহান

63

"স্প্রিং বুট" উপায়টি ব্যবহার করা হয় CommandLineRunner। কেবল এই ধরণের শিম যুক্ত করুন এবং আপনি যেতে ভাল। স্প্রিং ৪.১ (বুট 1.2) এও রয়েছে SmartInitializingBeanযা সবকিছু শুরু করার পরে কলব্যাক পায়। এবং আছে SmartLifecycle(স্প্রিং 3 থেকে)।


এর কোন উদাহরণ? কোনও স্বেচ্ছাসেবীর মুহুর্তে কমান্ড লাইনের মাধ্যমে অ্যাপটি চলার পরে কি শিম কার্যকর করা সম্ভব?
এমিলিও

5
"স্বেচ্ছাচারিত মুহুর্ত" বলতে আপনি কী বোঝেন তা জানেন না। স্প্রিং বুট ব্যবহারকারী নির্দেশিকা এবং নমুনাগুলিতে একটি CommandLineRunner(এবং আরও নতুন ApplicationRunner) ব্যবহারের উদাহরণ রয়েছে : ডকস.স্প্রিং.ইউ / স্প্রিং-বুট / ডকস / বর্তমান / এসএনএপিএসএইচটি / রেফারেন্স /
ডেভ সায়ার

আমি খুঁজে পেয়েছি যে লাইফসাইকালটি অ্যাপ্লিকেশন শুরু / থামার পর্যায়ে অ্যাসিক্রোনাস কাজ সম্পাদন করার পছন্দযুক্ত বিকল্প এবং আমি কমান্ডলাইনরার এবং ইনিশিয়ালাইজিং বিনের মধ্যে অন্যান্য পার্থক্য চিহ্নিত করার চেষ্টা করছি, তবে সে সম্পর্কে কিছুই খুঁজে পাচ্ছি না।
সালজুয়াম

3
দম্পতি চলিত উদাহরণ কোড ব্যবহারCommandLineRunner
আলেক্সি Simonov

41

আপনি ব্যবহার করে কোনও শ্রেণি প্রসারিত করতে পারেন ApplicationRunner, run()পদ্ধতিটিকে ওভাররাইড এবং সেখানে কোড যুক্ত করতে পারেন।

import org.springframework.boot.ApplicationRunner;

@Component
public class ServerInitializer implements ApplicationRunner {

    @Override
    public void run(ApplicationArguments applicationArguments) throws Exception {

        //code goes here

    }
}

স্প্রিং বুটে পারফেক্ট। ক্লাসের জন্য অ্যাপ্লিকেশন ব্যবহার করার সময় রান () পদ্ধতিটি দু'বার কল করা হয়েছিল। সুতরাং উপরের সাথে পোস্টকন্সট্রাক্ট পদ্ধতিটি আরও ভাল কাজ করেছে।
স্যাম

26

ApplicationReadyEventআপনি যদি যে কাজটি সম্পাদন করতে চান তা সঠিক সার্ভার ক্রিয়াকলাপের প্রয়োজন না হলে সত্যই কার্যকর। পরিবর্তনের জন্য কিছু নিরীক্ষণের জন্য একটি অ্যাসিঙ্ক টাস্ক শুরু করা একটি ভাল উদাহরণ।

তবে, যদি কাজটি শেষ না হওয়া অবধি আপনার সার্ভারটি 'প্রস্তুত নয়' অবস্থায় থাকে তবে এটি কার্যকর করা ভাল SmartInitializingSingletonকারণ আপনি আগে কলব্যাক পাবেন আপনার আরএসটি পোর্টটি খোলা এবং আপনার সার্ভারটি ব্যবসায়ের জন্য খোলা আপনি ।

@PostConstructযে কাজগুলি কেবল একবারে ঘটতে হবে তার জন্য ব্যবহার করার প্রলোভন করবেন না । আপনি যখন একাধিকবার ডাকা হচ্ছে তা লক্ষ্য করবেন তখন আপনি একটি অভদ্র চমক পেয়ে যাবেন ...


এটি নির্বাচিত উত্তর হওয়া উচিত। @ অ্যান্ডি যেমন উল্লেখ করেছেন, বন্দরগুলি খোলার ঠিক আগে স্মার্টআইনিটাইজিংসিংটনকে ডাকা হয়।
শ্রীকান্ত

24

বসন্ত কনফিগারেশন সহ:

@Configuration
public class ProjectConfiguration {
    private static final Logger log = 
   LoggerFactory.getLogger(ProjectConfiguration.class);

   @EventListener(ApplicationReadyEvent.class)
   public void doSomethingAfterStartup() {
    log.info("hello world, I have just started up");
  }
}

12

SmartInitializingSingletonবসন্তে শিম ব্যবহার করুন > ৪.১

@Bean
public SmartInitializingSingleton importProcessor() {
    return () -> {
        doStuff();
    };

}

বিকল্প হিসাবে একটি CommandLineRunnerমটরশুটি প্রয়োগ করা যেতে পারে বা এর সাথে একটি শিম পদ্ধতিটি বর্ননা করা যেতে পারে @PostConstruct


আমি কি সেই পদ্ধতির অভ্যন্তরে একটি স্বতঃপ্রযুক্ত নির্ভরতা প্রয়োজন? আমি প্রোফাইলগুলি সেট করতে চাই
LppEdd

7

ডেভ সিয়ার উত্তরের জন্য একটি উদাহরণ প্রদান, যা কবজির মতো কাজ করেছে:

@Component
public class CommandLineAppStartupRunner implements CommandLineRunner {
    private static final Logger logger = LoggerFactory.getLogger(CommandLineAppStartupRunner.class);

    @Override
    public void run(String...args) throws Exception {
        logger.info("Application started with command-line arguments: {} . \n To kill this application, press Ctrl + C.", Arrays.toString(args));
    }
}

7

এটি ব্যবহার করে দেখুন এবং অ্যাপ্লিকেশন প্রসঙ্গটি পুরোপুরি শুরু হয়ে গেলে এটি আপনার কোডটি চালাবে।

 @Component
public class OnStartServer implements ApplicationListener<ContextRefreshedEvent> {

    @Override
    public void onApplicationEvent(ContextRefreshedEvent arg0) {
                // EXECUTE YOUR CODE HERE 
    }
}

6

আমি খুব বেশি পরিষ্কার EventListenerহওয়ায় @ কেহেন ( https://stackoverflow.com/a/44923402/9122660 ) দ্বারা টীকাটি ব্যবহারের পরামর্শটি আমি সত্যিই পছন্দ করি । দুর্ভাগ্যক্রমে আমি এটি একটি স্প্রিং + কোটলিন সেটআপে কাজ করতে পারিনি। কোটলিনের জন্য কী কাজ করে তা ক্লাসটিকে মেথড প্যারামিটার হিসাবে যুক্ত করছে:

@EventListener 
fun doSomethingAfterStartup(event: ApplicationReadyEvent) {
    System.out.println("hello world, I have just started up");
}

এলোমেলোভাবে বাহিরে না বসন্ত বুট অ্যাপ্লিকেশন ক্লাস এ রাখুন@SpringBootApplication class MyApplication { @EventListener(ApplicationReadyEvent::class) fun doSomethingAfterStartup() { println("hello world, I have just started up") } }
আহমেদ না

আপনার এটির দরকার নেই @ স্প্রিংবুট অ্যাপ্লিকেশন ক্লাসে। যে কোনও কনফিগারেশন ক্লাস করবে
জর্জ মেরিন

5

স্প্রিং বুট অ্যাপ্লিকেশন শুরু হওয়ার পরে কোডের ব্লক কার্যকর করার সর্বোত্তম উপায় হ'ল পোস্টকন্সট্রাক্ট টীকা ব্যবহার করা। বা এছাড়াও আপনি একই জন্য কমান্ড লাইন রানার ব্যবহার করতে পারেন।

1. পোস্ট কনস্ট্রাক্ট টিকা ব্যবহার করে

@Configuration
public class InitialDataConfiguration {

    @PostConstruct
    public void postConstruct() {
        System.out.println("Started after Spring boot application !");
    }

}

2. কমান্ড লাইন রানার শিম ব্যবহার করে

@Configuration
public class InitialDataConfiguration {

    @Bean
    CommandLineRunner runner() {
        return args -> {
            System.out.println("CommandLineRunner running in the UnsplashApplication class...");
        };
    }
}

3

কেবল বসন্ত বুট অ্যাপ্লিকেশনের জন্য কমান্ডলাইনর্নার প্রয়োগ করুন। আপনাকে রান পদ্ধতিটি প্রয়োগ করতে হবে,

public classs SpringBootApplication implements CommandLineRunner{

    @Override
        public void run(String... arg0) throws Exception {
        // write your logic here 

        }
}

0

আপনি কমান্ডলাইনরার বা অ্যাপ্লিকেশন রুনার ব্যবহারের সর্বোত্তম উপায় রান () পদ্ধতির মধ্যে কেবলমাত্র পার্থক্য হ'ল কমান্ডলাইনরুনার স্ট্রিংয়ের অ্যারে গ্রহণ করে এবং অ্যাপ্লিকেশন রুনার অ্যাপ্লিকেশন অরগমেন্টটি গ্রহণ করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.