বসন্তের শুরুতে পদ্ধতিটি কার্যকর করুন


176

অ্যাপ্লিকেশন প্রথমবারের জন্য শুরু হলে কিছু পদ্ধতি কার্যকর করার জন্য কি কোনও স্প্রিং 3 বৈশিষ্ট্য রয়েছে? আমি জানি যে আমি @Scheduledটীকা দিয়ে কোনও পদ্ধতি নির্ধারণের কৌশলটি করতে পারি এবং এটি শুরু হওয়ার ঠিক পরে কার্যকর হয় তবে এর পরে এটি পর্যায়ক্রমে কার্যকর হবে।


1
@ নির্ধারিত সাথে কৌশলটি কি? ঠিক এটাই আমি চাই!
ক্রিসমার্ক

উত্তর:


185

যদি "অ্যাপ্লিকেশন স্টার্টআপ" দ্বারা আপনি "অ্যাপ্লিকেশন প্রসঙ্গ শুরু" বলতে বোঝায়, তবে হ্যাঁ, এটি করার অনেকগুলি উপায় রয়েছে , আপনার পদ্ধতিটি বর্ননা করা সবচেয়ে সহজ (একক শিমের জন্য, যাইহোক) @PostConstruct। অন্যান্য বিকল্পগুলি দেখতে লিঙ্কটি একবার দেখুন, তবে সংক্ষেপে সেগুলি হ'ল:

  • পদ্ধতিগুলি সহ টীকাগুলি @PostConstruct
  • afterPropertiesSet()InitializingBeanকলব্যাক ইন্টারফেস দ্বারা সংজ্ঞায়িত
  • একটি কাস্টম কনফিগার করা init () পদ্ধতি

টেকনিক্যালি, এই মধ্যে আঙ্গুলসমূহ হয় শিম জীবনচক্র বদলে প্রসঙ্গ জীবনচক্র কিন্তু মামলার 99%, দুই সমতুল্য।

আপনার যদি প্রসঙ্গত প্রারম্ভ / শাটডাউনটি বিশেষভাবে আঁকতে হয় তবে আপনি পরিবর্তে ইন্টারফেসটি প্রয়োগLifecycle করতে পারেন তবে এটি সম্ভবত অপ্রয়োজনীয়।


7
আমি বেশ কিছুটা গবেষণার পরেও লাইফসাইকেল বা স্মার্ট লাইফাইসাইকেলের একটি বাস্তবায়ন দেখতে পাইনি। আমি জানি এটি এক বছরের পুরনো, তবে স্ক্যাফম্যান যদি আপনার কাছে এমন কিছু থাকে যা আপনি পোস্ট করতে পারেন যা অনেক প্রশংসা হবে।

4
পুরো অ্যাপ্লিকেশন প্রসঙ্গটি তৈরি হওয়ার আগে উপরের পদ্ধতিগুলি ডাকা হবে (যেমন। / আগে / লেনদেনের সীমা নির্ধারণ করা হয়েছে)।
হ্যান্স ওয়েস্টারবিইক

আমি জাভা ১.৮ তে পোষ্টকন্সট্রাক্ট ব্যবহারের চেষ্টা করার সময় একটি অদ্ভুত সতর্কতা পেয়েছি:Access restriction: The type PostConstruct is not accessible due to restriction on required library /Library/Java/JavaVirtualMachines/jdk1.8.0_05.jdk/Contents/Home/jre/lib/rt.jar

2
এমন গুরুত্বপূর্ণ মামলা রয়েছে যেখানে শিম এবং প্রসঙ্গের জীবনচক্রটি খুব আলাদা। @ হ্যান্স ওয়েস্টারবাইক হিসাবে উল্লেখ করা হয়েছে যে একটি বিন এর প্রসঙ্গের উপর নির্ভর করে পুরোপুরি প্রস্তুত হওয়ার আগে সেটআপ করা যেতে পারে। আমার পরিস্থিতিতে একটি শিম জেএমএসের উপর নির্ভর করে - এটি সম্পূর্ণরূপে নির্মিত হয়েছিল, সুতরাং এটির @PostConstructপদ্ধতিটি বলা হয়েছিল, তবে জেএমএস ইনফ্রা-কাঠামো এটি পরোক্ষভাবে নির্ভর করে এখনও পুরোপুরি বিরক্ত হয়নি (এবং স্প্রিং হয়ে সবকিছু নিঃশব্দে ব্যর্থ হয়েছিল)। @EventListener(ApplicationReadyEvent.class)কাজ করা সমস্ত কিছুতে স্যুইচ করার সময় ( ApplicationReadyEventভ্যানিলা স্প্রিংয়ের জন্য স্প্রিং বুট নির্দিষ্ট স্টিফানের উত্তর দেখুন)।
জর্জ হকিন্স

@ স্কাফম্যান: আমার শিমটি যদি কোনও শিমের দ্বারা উল্লেখ না করা হয় এবং আমি কোথাও ব্যবহার না করে শিমটি শুরু করতে চাই
সাগর খারাব

104

এটি সহজেই একটি দ্বারা সম্পন্ন হয় ApplicationListener। আমি স্প্রিংয়ের শোনার জন্য এটি পেয়েছিলাম ContextRefreshedEvent:

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class StartupHousekeeper implements ApplicationListener<ContextRefreshedEvent> {

  @Override
  public void onApplicationEvent(final ContextRefreshedEvent event) {
    // do whatever you need here 
  }
}

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

হালনাগাদ

স্প্রিং ৪.২+ দিয়ে শুরু করে আপনি @EventListenerটীকাটি পর্যবেক্ষণ করতেও ব্যবহার করতে পারেন ContextRefreshedEvent( এটি নির্দেশ করার জন্য @ ফিলিপিনিককে ধন্যবাদ ):

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;

@Component
public class StartupHousekeeper {

  @EventListener(ContextRefreshedEvent.class)
  public void contextRefreshedEvent() {
    // do whatever you need here 
  }
}

1
এটি আমার পক্ষেও কাজ করেছে - এক সময়ের নন-শিম আরম্ভের জন্য উপযুক্ত।
ররি হান্টার

9
ContextStartedEventপরিবর্তে ব্যবহারের জন্য প্রলোভিতদের জন্য এনবি , ইভেন্টটি চালুর আগে শ্রোতাদের যুক্ত করা আরও কঠিন।
অরেঞ্জডগ

2
কীভাবে একজন @ সমর্থিত জেপিএ সংগ্রহস্থলকে কল করবেন? ভান্ডারটি নাল।
ই তথ্য 128

আমার জন্য কাজ করছে না। আমি স্প্রিং এমভিসি 3 ব্যবহার করছি App অ্যাপ্লিকেশনএভেন্ট (___) এ মেহোদ অ্যাপ্লিকেশন শুরু হওয়ার পরে কল হয় না। কোন সাহায্য. এখানে আমার কোড @ কম্পোনেন্ট পাবলিক ক্লাস অ্যাপস্টার্টলিস্টনার অ্যাপ্লিকেশনলিস্টার প্রয়োগ করে <কনটেক্সটরিফ্রেসড এভেন্ট> App পাবলিক বায়োড অনপ্লিকেশন-এভেন্ট (চূড়ান্ত কনটেক্সট রেফারশেড ইভেন্ট) {System.out.println ("\ n \ n application n অ্যাপ্লিকেশন ইভেন্টের ভিতরে"); }}
বিশ্বাস ত্যাগী

@ વિશ্যাসতিয়াগি আপনি কীভাবে আপনার ধারক শুরু করবেন? আপনি কি নিশ্চিত যে আপনার অ্যাপস্টার্টলিস্টনারটি আপনার উপাদান স্ক্যানের অংশ?
স্টিফান হ্যাবারেল

38

বসন্তে 4.2+ এ আপনি এখন সহজভাবে করতে পারেন:

@Component
class StartupHousekeeper {

    @EventListener(ContextRefreshedEvent.class)
    public void contextRefreshedEvent() {
        //do whatever
    }
}

এই শ্রোতা কি একবারেই শুরু হওয়ার পরে একবার অনুরোধ করে তার নিশ্চয়তা আছে?
gstackoverflow

না, আমার উত্তর উপরে দেখুন। এটি প্রথমবারের জন্য কার্যকর হচ্ছে কিনা তা যাচাই করার জন্য আপনার শ্রোতার মধ্যে কিছু
স্থিতি রাখুন

13

আপনি যদি বসন্ত-বুট ব্যবহার করেন তবে এটি সেরা উত্তর।

আমি অনুভব করি @PostConstructএবং অন্যান্য বিভিন্ন জীবনচক্রের আন্তঃব্যক্তিগুলি প্রায় রাস্তা। এগুলি সরাসরি রানটাইম সমস্যাগুলিতে ডেকে আনতে পারে বা অপ্রত্যাশিত শিম / প্রসঙ্গ লাইফসাইকেলের ইভেন্টের কারণে সুস্পষ্ট ত্রুটিগুলির তুলনায় কম ঘটায়। প্লেইন জাভা ব্যবহার করে কেবল আপনার শিমকে সরাসরি অনুরোধ করবেন না কেন? আপনি এখনও শিমকে 'বসন্তের পথে' (যেমন: বসন্তের এওপি প্রক্সি মাধ্যমে) প্রার্থনা করেন। এবং সর্বোপরি, এটি সরল জাভা, এর চেয়ে সহজতর কোনওটি পেতে পারে না। প্রসঙ্গ শ্রোতা বা বিজোড় শিডিয়ুলারের প্রয়োজন নেই।

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext app = SpringApplication.run(DemoApplication.class, args);

        MyBean myBean = (MyBean)app.getBean("myBean");

        myBean.invokeMyEntryPoint();
    }
}

5
এটি সাধারণভাবে একটি ভাল ধারণা তবে যখন আপনার বসন্তের অ্যাপ্লিকেশন প্রসঙ্গে ইন্টিগ্রেশন পরীক্ষা থেকে শুরু করা হয়, মূল কখনই চালানো হয় না!
জোনাস গিরিগ্যাট

@ জোনাস জিয়ারগ্যাট: প্লাস, এমন অন্যান্য পরিস্থিতি রয়েছে যেখানে কিছু নেই main(), উদাহরণস্বরূপ অ্যাপ্লিকেশন কাঠামো ব্যবহার করার সময় (যেমন জাভাসবার সার্ভিস)।
sleske

9

@ পোস্টকনস্ট্রাক্ট টিকা টীকাটি উল্লেখ করার সময় জাভা ১.৮ ব্যবহারকারীর জন্য একটি সতর্কতা পাওয়া যাচ্ছে, আমি @ স্কুলেড এনটোটেশনটি বন্ধ করে দিয়েছিলাম তবে আপনি যদি ইতিমধ্যে ফিক্সট্রেট বা ফিক্সডলে সাথে একটি @ নির্ধারিত কাজ পেয়ে থাকেন তবে আপনি তা করতে পারেন।

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

@EnableScheduling
@Component
public class ScheduledTasks {

private static final Logger LOGGER = LoggerFactory.getLogger(ScheduledTasks.class);

private static boolean needToRunStartupMethod = true;

    @Scheduled(fixedRate = 3600000)
    public void keepAlive() {
        //log "alive" every hour for sanity checks
        LOGGER.debug("alive");
        if (needToRunStartupMethod) {
            runOnceOnlyOnStartup();
            needToRunStartupMethod = false;
        }
    }

    public void runOnceOnlyOnStartup() {
        LOGGER.debug("running startup job");
    }

}


7

আমরা যা করেছি তা org.springframework.web.context.ContextLoaderListenerপ্রিন্ট শুরু হওয়ার সাথে সাথে কিছু মুদ্রণের প্রসারিত ছিল ।

public class ContextLoaderListener extends org.springframework.web.context.ContextLoaderListener
{
    private static final Logger logger = LoggerFactory.getLogger( ContextLoaderListener.class );

    public ContextLoaderListener()
    {
        logger.info( "Starting application..." );
    }
}

সাবক্লাসটি তখন কনফিগার করুন এতে web.xml:

<listener>
    <listener-class>
        com.mycomp.myapp.web.context.ContextLoaderListener
    </listener-class>
</listener>

7

স্প্রিংবুট দিয়ে, আমরা @EventListenerটিকা-র মাধ্যমে স্টার্টআপে একটি পদ্ধতি কার্যকর করতে পারি

@Component
public class LoadDataOnStartUp
{   
    @EventListener(ApplicationReadyEvent.class)
    public void loadData()
    {
        // do something
    }
}

4

মনোযোগ দিন, যদি কেবলমাত্র আপনার runOnceOnStartupপদ্ধতিটি সম্পূর্ণরূপে বসন্তের প্রসঙ্গে নির্ভর করে তবেই এটির পরামর্শ দেওয়া হয়। উদাহরণস্বরূপ: আপনি লেনদেনের সীমাবদ্ধতার সাথে একটি দাও কল করতে চান

আপনি স্থিরডেলি সেটটি খুব উঁচু করে একটি নির্ধারিত পদ্ধতিও ব্যবহার করতে পারেন

@Scheduled(fixedDelay = Long.MAX_VALUE)
public void runOnceOnStartup() {
    dosomething();
}

এতে পুরো সুবিধাটি শেষ হয়ে যাওয়ার সুবিধা রয়েছে (লেনদেন, দাও, ...)

স্প্রিং টাস্ক নেমস্পেস ব্যবহার করে একবার চালানোর জন্য সময় নির্ধারণের কাজগুলিতে দেখা যায়


আমি ব্যবহার করে কোন সুবিধা দেখতে পাচ্ছি না @PostConstruct?
উইম দেবলাউয়ে

@ উইমডাব্লাউউ ডোজোমেটিংয়ে আপনি যা করতে চান তার উপর নির্ভর করে () ট্র্যাজিকেশন ডেমার্কেশন দিয়ে একটি অটোভায়ার্ড দাও কল করতে পুরো প্রসঙ্গটি শুরু করা দরকার, কেবল এই শিমটি নয়
জোরাম

5
@ উইমডেব্লাউউ '@ পোষ্টকনস্ট্রাক্ট' পদ্ধতিটি শিমটি শুরু করা হলে পুরো প্রসঙ্গটি প্রস্তুত নাও হতে পারে (ফে ট্রানজেকশন ম্যানেজমেন্ট)
জোরাম

পোস্ট নির্মাণ বা কোনও ইন্টারফেস বা ইভেন্টের চেয়ে এটি আরও মার্জিত ইমো
aliopi

1

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

স্প্রিং কনফিগারেশনের মাধ্যমে ডিফল্ট লোকেল এবং টাইমজোন সূচনা করুন


1
AppStartListener implements ApplicationListener {
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if(event instanceof ApplicationReadyEvent){
            System.out.print("ciao");

        }
    }
}

2
অ্যাপ্লিকেশনরিডিভেন্টটি বসন্ত বুটে 3 টি বসন্তে নয়
জন মার্সিয়ের

0

আপনার অ্যাপ্লিকেশন পুরোপুরি চলার আগে আপনি যদি শিমটি কনফিগার করতে চান তবে আপনি ব্যবহার করতে পারেন @Autowired:

@Autowired
private void configureBean(MyBean: bean) {
    bean.setConfiguration(myConfiguration);
}

0

আপনি @EventListenerআপনার উপাদানটিতে ব্যবহার করতে পারেন যা সার্ভারটি শুরু হওয়ার পরে এবং সমস্ত মটরশুটি শুরু করার পরে শুরু করা হবে।

@EventListener
public void onApplicationEvent(ContextClosedEvent event) {

}

0

StartupHousekeeper.javaপ্যাকেজে অবস্থিত একটি ফাইলের জন্য com.app.startup,

এটি এখানে করুন StartupHousekeeper.java:

@Component
public class StartupHousekeeper {

  @EventListener(ContextRefreshedEvent.class)
  public void keepHouse() {
    System.out.println("This prints at startup.");
  }
}

এবং এটি এতে করুন myDispatcher-servlet.java:

<?xml version="1.0" encoding="UTF-8"?>
<beans>

    <mvc:annotation-driven />
    <context:component-scan base-package="com.app.startup" />

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