বসন্তে কোয়ার্টজ কাজের সিমের রেফারেন্স ইনজেক্ট করবেন?


95

আমি বসন্তে জবস্টোরটিএক্স স্ট্রিন্ট স্টোর ব্যবহার করে একটি কোয়ার্টজ জব কনফিগার এবং সময়সূচী পরিচালনা করেছি আমি স্প্রিংয়ের কোয়ার্টজ কাজগুলি ব্যবহার করি না, কারণ আমি তাদের চলাকালীন সময়ে গতিশীলভাবে শিডিউল করা দরকার, এবং কোয়ার্টজের সাথে স্প্রিংকে সংহত করার সমস্ত উদাহরণ যা আমি পেয়েছি যে স্প্রিং কনফিগারেশন ফাইলগুলিতে শিডিউলগুলি হার্ড-কোডিং ছিল ... যাইহোক, এখানে কীভাবে হয় আমি কাজের সময়সূচী:

JobDetail emailJob = JobBuilder.newJob(EMailJob.class)
.withIdentity("someJobKey", "immediateEmailsGroup")
.storeDurably()
.build();

SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() 
.withIdentity("someTriggerKey", "immediateEmailsGroup")
.startAt(fireTime)
.build();

// pass initialization parameters into the job
emailJob.getJobDataMap().put(NotificationConstants.MESSAGE_PARAMETERS_KEY,       messageParameters);
emailJob.getJobDataMap().put(NotificationConstants.RECIPIENT_KEY, recipient);

if (!scheduler.checkExists(jobKey) && scheduler.getTrigger(triggerKey) != null)     {                                       
// schedule the job to run
Date scheduleTime1 = scheduler.scheduleJob(emailJob, trigger);
}

ইমেলজব একটি সহজ কাজ যা স্প্রিংয়ের জাভামেলসেন্ডারআইএমপিএল ক্লাসটি ব্যবহার করে ইমেল প্রেরণ করে।

public class EMailJob implements Job {
@Autowired
private JavaMailSenderImpl mailSenderImpl;

    public EMailJob() {
    }
    public void execute(JobExecutionContext context)
       throws JobExecutionException {
   ....
    try {
        mailSenderImpl.send(mimeMessage);
    } catch (MessagingException e) {
        ....
        throw new JobExecutionException("EMailJob failed: " +  jobKey.getName(), e);
    }

    logger.info("EMailJob finished OK");

}

সমস্যাটি হ'ল আমার ই-মেইলজব ক্লাসে এই শ্রেণীর (জাভামেলসেন্ডারআইএমপিএল) উদাহরণের একটি রেফারেন্স পাওয়া দরকার get যখন আমি এটির মতো ইঞ্জেক্ট করার চেষ্টা করি:

@Autowired
private JavaMailSenderImpl mailSenderImpl;

এটি ইনজেকশনের নয় - রেফারেন্সটি NULL। আমি ধরে নিচ্ছি যে এটি ঘটছে কারণ এটি স্প্রিং নয় যারা ইমেইলজব ক্লাসটি ইনস্ট্যান্ট করে তবে কোয়ার্টজ এবং কোয়ার্টজ নির্ভরতা ইনজেকশন সম্পর্কে কিছুই জানেন না ...

সুতরাং, এই ইঞ্জেকশনটি ঘটতে বাধ্য করার কোনও উপায় আছে?

ধন্যবাদ!

আপডেট 1: @ অ্যারন: এটি শুরু থেকে স্ট্যাকট্রেসের একটি প্রাসঙ্গিক অংশ, যা দেখায় যে ইমেইলজব দু'বার ইনস্ট্যান্ট করা হয়েছিল:

2011-08-15 14:16:38,687 [main] INFO     org.springframework.context.support.GenericApplicationContext - Bean 'org.springframework.security.access.expression.method.DefaultMethodSecurityExpressionHandler#0' is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
2011-08-15 14:16:38,734 [main] INFO  org.springframework.beans.factory.support.DefaultListableBeanFactory - Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@1328c7a: defining beans [...]; root of factory hierarchy
2011-08-15 14:16:39,734 [main] INFO  com.cambridgedata.notifications.EMailJob - EMailJob() -  initializing ...
2011-08-15 14:16:39,937 [main] INFO  org.springframework.security.access.intercept.aopalliance.MethodSecurityInterceptor -   Validated configuration attributes
2011-08-15 14:16:40,078 [main] INFO  org.springframework.security.web.access.intercept.FilterSecurityInterceptor - Validated configuration attributes
2011-08-15 14:16:40,296 [main] INFO  org.springframework.jdbc.datasource.init.ResourceDatabasePopulator - Executing SQL script from class path resource ...
2011-08-15 14:17:14,031 [main] INFO  com.mchange.v2.log.MLog - MLog clients using log4j logging.
2011-08-15 14:17:14,109 [main] INFO  com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10]
2011-08-15 14:17:14,171 [main] INFO  org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2011-08-15 14:17:14,171 [main] INFO  org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.0.1 created.
2011-08-15 14:17:14,187 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Using thread monitor-based data access locking (synchronization).
2011-08-15 14:17:14,187 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized.
2011-08-15 14:17:14,187 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.1) 'NotificationsScheduler' with instanceId  'NON_CLUSTERED'
 Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
   NOT STARTED.
 Currently in standby mode.
 Number of jobs executed: 0
 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
 Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered.

2011-08-15 14:17:14,187 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'NotificationsScheduler' initialized from the specified file : 'spring/quartz.properties' from the class resource path.
2011-08-15 14:17:14,187 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.0.1
2011-08-15 14:17:14,234 [main] INFO  com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 2sajb28h1lcabf28k3nr1|13af084, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 2sajb28h1lcabf28k3nr1|13af084, idleConnectionTestPeriod -> 50, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/2010rewrite2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 5, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> select 0 from dual, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
2011-08-15 14:17:14,312 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Freed 0 triggers from 'acquired' / 'blocked' state.
2011-08-15 14:17:14,328 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Recovering 0 jobs that were in-progress at the time of the last shut-down.
2011-08-15 14:17:14,328 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Recovery complete.
2011-08-15 14:17:14,328 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 'complete' triggers.
2011-08-15 14:17:14,328 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 stale fired job entries.
2011-08-15 14:17:14,328 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler NotificationsScheduler_$_NON_CLUSTERED started.
2011-08-15 14:17:14,515 [NotificationsScheduler_QuartzSchedulerThread] INFO  com.cambridgedata.notifications.EMailJob - EMailJob() -  initializing ...

ধন্যবাদ!

আপডেট # 2: @ রায়ান:

আমি নীচে স্প্রিংবিয়ানজব ফ্যাক্টরিটি ব্যবহার করার চেষ্টা করেছি:

    <bean id="jobFactoryBean" class="org.springframework.scheduling.quartz.SpringBeanJobFactory">
</bean>

<bean id="schedulerFactoryBean" class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="configLocation" value="classpath:spring/quartz.properties"/>
        <property name="jobFactory" ref="jobFactoryBean"/>
</bean>

এবং আমি এই কারখানাটি থেকে কোয়ার্টজ-এর পরিবর্তে এই কারখানাটি থেকে শিডিয়ুলার পেতে আমার মূল শ্রেণিকে সংশোধন করেছি:

    @PostConstruct
public void initNotificationScheduler() {
    try {
        //sf = new StdSchedulerFactory("spring/quartz.properties");
        //scheduler = sf.getScheduler();

        scheduler = schedulerFactoryBean.getScheduler();
        scheduler.start();
            ....

তবে আমি যখন অ্যাপটি চালাচ্ছি - ত্রুটিগুলি পান, নীচে দেখুন। স্প্রিং স্টার্টআপ থেকে স্ট্যাকট্রেস এখানে। সময়সূচীটি নিজেই সূক্ষ্মভাবে তৈরি হয়েছে বলে মনে হয়, তবে ত্রুটি তখনই আসে যখন এটি আমার ইমেইলজব ইনস্ট্যান্ট করার চেষ্টা করছে:

2011-08-15 21:49:42,968 [main] INFO  org.springframework.scheduling.quartz.SchedulerFactoryBean - Loading Quartz config from [class path resource [spring/quartz.properties]]
2011-08-15 21:49:43,031 [main] INFO  com.mchange.v2.log.MLog - MLog clients using log4j logging.
2011-08-15 21:49:43,109 [main] INFO  com.mchange.v2.c3p0.C3P0Registry - Initializing c3p0-0.9.1.1 [built 15-March-2007 01:32:31; debug? true; trace: 10]
2011-08-15 21:49:43,187 [main] INFO  org.quartz.core.SchedulerSignalerImpl - Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
2011-08-15 21:49:43,187 [main] INFO  org.quartz.core.QuartzScheduler - Quartz Scheduler v.2.0.1 created.
2011-08-15 21:49:43,187 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Using thread monitor-based data access locking (synchronization).
2011-08-15 21:49:43,187 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - JobStoreTX initialized.
2011-08-15 21:49:43,187 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler meta-data: Quartz Scheduler (v2.0.1) 'schedulerFactoryBean' with instanceId 'NON_CLUSTERED'
 Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
 NOT STARTED.
 Currently in standby mode.
 Number of jobs executed: 0
 Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 3 threads.
 Using job-store 'org.quartz.impl.jdbcjobstore.JobStoreTX' - which supports persistence. and is not clustered.

2011-08-15 21:49:43,187 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler 'schedulerFactoryBean' initialized from an externally provided properties instance.
2011-08-15 21:49:43,187 [main] INFO  org.quartz.impl.StdSchedulerFactory - Quartz scheduler version: 2.0.1
2011-08-15 21:49:43,187 [main] INFO  org.quartz.core.QuartzScheduler - JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory@566633
2011-08-15 21:49:43,265 [main] INFO  com.mchange.v2.c3p0.impl.AbstractPoolBackedDataSource - Initializing c3p0 pool... com.mchange.v2.c3p0.ComboPooledDataSource [ acquireIncrement -> 3, acquireRetryAttempts -> 30, acquireRetryDelay -> 1000, autoCommitOnClose -> false, automaticTestTable -> null, breakAfterAcquireFailure -> false, checkoutTimeout -> 0, connectionCustomizerClassName -> null, connectionTesterClassName -> com.mchange.v2.c3p0.impl.DefaultConnectionTester, dataSourceName -> 1hge13f8h1lsg7py1rg0iu0|1956391, debugUnreturnedConnectionStackTraces -> false, description -> null, driverClass -> com.mysql.jdbc.Driver, factoryClassLocation -> null, forceIgnoreUnresolvedTransactions -> false, identityToken -> 1hge13f8h1lsg7py1rg0iu0|1956391, idleConnectionTestPeriod -> 50, initialPoolSize -> 3, jdbcUrl -> jdbc:mysql://localhost:3306/2010rewrite2, lastAcquisitionFailureDefaultUser -> null, maxAdministrativeTaskTime -> 0, maxConnectionAge -> 0, maxIdleTime -> 0, maxIdleTimeExcessConnections -> 0, maxPoolSize -> 5, maxStatements -> 0, maxStatementsPerConnection -> 120, minPoolSize -> 1, numHelperThreads -> 3, numThreadsAwaitingCheckoutDefaultUser -> 0, preferredTestQuery -> select 0 from dual, properties -> {user=******, password=******}, propertyCycle -> 0, testConnectionOnCheckin -> true, testConnectionOnCheckout -> false, unreturnedConnectionTimeout -> 0, usesTraditionalReflectiveProxies -> false ]
2011-08-15 21:49:43,343 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Freed 0 triggers from 'acquired' / 'blocked' state.
2011-08-15 21:49:43,359 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Recovering 0 jobs that were in-progress at the time of the last shut-down.
2011-08-15 21:49:43,359 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Recovery complete.
2011-08-15 21:49:43,359 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 'complete' triggers.
2011-08-15 21:49:43,359 [main] INFO  org.quartz.impl.jdbcjobstore.JobStoreTX - Removed 0 stale fired job entries.
2011-08-15 21:49:43,359 [main] INFO  org.quartz.core.QuartzScheduler - Scheduler schedulerFactoryBean_$_NON_CLUSTERED started.
2011-08-15 21:49:43,562 [schedulerFactoryBean_QuartzSchedulerThread] ERROR org.quartz.core.ErrorLogger - An error occured instantiating job to be executed. job= 'immediateEmailsGroup.DEFAULT.jobFor_1000new1'
org.quartz.SchedulerException: Problem instantiating class  'com.cambridgedata.notifications.EMailJob' -  [See nested exception:  java.lang.AbstractMethodError:  org.springframework.scheduling.quartz.SpringBeanJobFactory.newJob(Lorg/quartz/spi/TriggerFiredBundle;Lorg/quartz/Scheduler;)Lorg/quartz/Job;]
at org.quartz.core.JobRunShell.initialize(JobRunShell.java:141)
at org.quartz.core.QuartzSchedulerThread.run(QuartzSchedulerThread.java:381)
Caused by: java.lang.AbstractMethodError: org.springframework.scheduling.quartz.SpringBeanJobFactory.newJob(Lorg/quartz/spi/TriggerFiredBundle;Lorg/quartz/Scheduler;)Lorg/quartz/Job;
at org.quartz.core.JobRunShell.initialize(JobRunShell.java:134)

ধন্যবাদ!

উত্তর:


130

আপনি SpringBeanJobFactoryবসন্তটি ব্যবহার করে কোয়ার্টজ অবজেক্টগুলিকে স্বয়ংক্রিয়ভাবে স্বতঃসংশ্লিষ্ট করতে এটি ব্যবহার করতে পারেন :

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
    ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}

তারপরে, এটি আপনার সাথে সংযুক্ত করুন SchedulerBean(এই ক্ষেত্রে, জাভা-কনফিগারেশনের সাথে):

@Bean
public SchedulerFactoryBean quartzScheduler() {
    SchedulerFactoryBean quartzScheduler = new SchedulerFactoryBean();

    ...

    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    quartzScheduler.setJobFactory(jobFactory);

    ...

    return quartzScheduler;
}

আমার জন্য কাজ করছে, বসন্ত -৩.২.১ এবং কোয়ার্টজ -২.১..6 ব্যবহার করে।

এখানে সম্পূর্ণ টুকরোটি দেখুন ।

আমি এই ব্লগ পোস্টে সমাধান খুঁজে পেয়েছি


13
আপনার এটির জন্য একটি পুরস্কার জিতানো উচিত, এটি দুর্দান্ত is
নাথান ফেজার

4
সমাধানটি আসলেই দুর্দান্ত! ব্লগ পোস্টটির লেখকের সমস্ত ক্রেডিট :)
জেলি

4
ধন্যবাদ - এটি আমার দিনগুলি রক্ষা করেছে! কেন স্প্রিং এই OOB সরবরাহ করেনি। স্প্রিংয়ে কোয়ার্টজ ব্যবহারের জন্য এটি খুব প্রাথমিক প্রয়োজন।
হ্যান্ডিম্যানড্যান

4
এটি ডিফল্ট বাস্তবায়ন হওয়া উচিত :)
ডিয়েগো প্লেন্টজ

4
দুর্দান্ত সমাধান, তবে কারও কোনও ধারণা আছে যে কেন অটোয়ারক্যাপেবল বিয়ানফ্যাক্টরী বিয়ানফ্যাক্টরিটিকে "ক্ষণস্থায়ী" হিসাবে চিহ্নিত করা হয়েছে? অটোয়ারিংস্প্রিংবিয়ানজব ফ্যাক্টরি যাইহোক সিরিয়ালাইজড বলে মনে হয় না, তাই বিয়ান ফ্যাক্টরিরও আর কখনও সিরিয়ালাইজ করার প্রয়োজন হবে না
মারিওস

57

আমি SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);আমার Job.execute(JobExecutionContext context)পদ্ধতির প্রথম লাইন হিসাবে রেখেছি ।


7
এটিই আসল সমাধান। স্প্রিংয়ের সাথে পরীক্ষিত 3.2.4. রিলিজ এবং কোয়ার্টজ 2.2.0। ;)
aloplop85

4
@ ম্যাসাঙ্গেল - ভাল, উভয়ই কাজ করবে, তবে আপনার কোয়ার্টজ চাকরিতে স্প্রিংবিয়ানআউটউইরিংস সমর্থনটি ব্যবহারের ক্ষেত্রে সমস্যাটি হ'ল কাজের কাজের জন্য এখন স্প্রিং সম্পর্কে জানতে হবে, যা আইওসি (ডিপ ইনজেকশন) এর সম্পূর্ণ ধারণার বিপরীতে রয়েছে। আপনি যদি এখন উদাহরণস্বরূপ সিডিআই ব্যবহার করতে চান তবে আপনার সমস্ত কোয়ার্টজ কাজগুলি কেবলমাত্র একটি কাজের কারখানার পরিবর্তে সামঞ্জস্য করা দরকার।
দেমানিয়াক

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

4
এই সমাধানটি বসন্ত ৪.১.৪ এবং কোয়ার্টজ ২.২.১- এর সাথে কাজ করে না
স্কাইওয়াকার

4
আমারও এই সমস্যা ছিল এবং আমি এই সমাধানটি চেষ্টা করেছিলাম। এটি কাজ করছে তবে এটি ইতিমধ্যে তৈরি হওয়া (ডিফল্ট সিঙ্গলটন) ব্যবহার না করে একটি নতুন উদাহরণ তৈরি করে। যাইহোক আপনি শিডিয়্যারেটার.জেটকন্টেক্সট () ব্যবহার করে আপনার চাকরিতে যে কোনও কিছু পাস করতে পারেন put ("অবজেক্টনাম", অবজেক্ট);
ক্রিজিসটফ সিলেলিস্কি

13

লিঙ্কে একই সমস্যা সমাধান করা হয়েছে :

আমি স্প্রিং ফোরামের পোস্ট থেকে অন্য বিকল্পটি পেয়েছি যা আপনি শিডিয়ুলফ্যাক্টরিবিয়ান এর মাধ্যমে স্প্রিং অ্যাপ্লিকেশন প্রসঙ্গে একটি রেফারেন্স দিতে পারেন। নীচে প্রদর্শিত উদাহরণ মত:

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
<propertyy name="triggers">
    <list>
        <ref bean="simpleTrigger"/>
            </list>
    </property>
    <property name="applicationContextSchedulerContextKey">
        <value>applicationContext</value>
</property>

তারপরে আপনার চাকরির ক্লাসে নীচের কোড ব্যবহার করে আপনি অ্যাপ্লিকেশন কনটেক্সট পেতে পারেন এবং যা চান সিম পেতে পারেন।

appCtx = (ApplicationContext)context.getScheduler().getContext().get("applicationContextSchedulerContextKey");

আশা করি এটা সাহায্য করবে. আপনি মার্ক ম্যাকলারেনস ব্লগ থেকে আরও তথ্য পেতে পারেন


4
ধন্যবাদ, @ রিপন! অনেক চেষ্টা এবং ব্যর্থ হওয়ার পরেও, আপনি প্রস্তাবিত একটি অনুরূপ পন্থা ব্যবহার করেছি: আমি অ্যাপ্লিকেশন কনটেক্সটস্চুলারকন্টেক্সটকি সম্পত্তি এবং অ্যাপ্লিকেশন প্রসঙ্গটি ব্যবহার করি নি, তবে আমি 'কোড' <সম্পত্তি নাম = "সময়সূচককন্টেক্সটএসম্যাপ"> <ম্যাপ> <এন্ট্রি কী = ব্যবহার করেছি "মেইল সার্ভিস" মান-রেফ = "মেল সার্ভিস" /> </map> </property>
মেরিনা

8

আপনি স্প্রিং বনাম কোয়ার্টজ ক্লাসটি ইনস্ট্যান্ট করে তোলার বিষয়ে আপনার ধারনা ঠিক রেখেছেন। যাইহোক, স্প্রিং কিছু ক্লাস সরবরাহ করে যা আপনাকে কোয়ার্টজে কিছু প্রাথমিক নির্ভরতা ইনজেকশন করতে দেয়। পরীক্ষা করে দেখুন SchedulerFactoryBean.setJobFactory () সহ SpringBeanJobFactory । মূলত, স্প্রিংবিয়ানজবফ্যাক্টরি ব্যবহার করে আপনি সমস্ত কাজের বৈশিষ্ট্যের উপর নির্ভরতা ইনজেকশন সক্ষম করেন তবে কেবল কোয়ার্টজ শিডিয়ুলার প্রসঙ্গে বা কাজের ডেটা ম্যাপে থাকা মানগুলির জন্য । আমি জানি না এটি যে সমস্ত ডিআই স্টাইল সমর্থন করে (কন্সট্রাক্টর, টিকা, সেটটার ...) তবে আমি জানি এটি সেটার ইনজেকশনকে সমর্থন করে।


হাই, রায়ান, আপনার পরামর্শের জন্য ধন্যবাদ। আপনি কি বোঝাতে চেয়েছেন যে নির্ভরতা ইনজেকশন সক্ষম করার জন্য আমাকে প্রি-কনফিগার করা ট্রিগার এবং কোয়ার্টজববিন প্রসারিত কাজগুলি সহ স্প্রিংবিয়ানফ্যাক্টরিজবটি ব্যবহার করতে হবে? এই পদ্ধতির সাথে সমস্যাটি হ'ল ট্রিগারগুলি স্প্রিংয়ের কনফিগারেশন ফাইলগুলিতে স্থিতিশীলভাবে সংজ্ঞায়িত করা হয়, যেখানে রানের সময় গতিশীল সময়সূচী সহ আমার ট্রিগারগুলি সংজ্ঞায়িত করতে সক্ষম হতে হবে ... আরও তথ্যের জন্য নীচের আমার পরবর্তী উত্তরটি দেখুন - পর্যাপ্ত স্থান নেই মন্তব্য অঞ্চল ...
মেরিনা

@ মারিনা: না, এটি কীভাবে কাজ করে তা নয়। স্প্রিংবিয়ানজবফ্যাক্টরি ব্যবহার করুন এবং আপনি যেভাবে এটি করতে চান তা করুন। এটা ঠিক কাজ করবে। এছাড়াও, এমন কোনও উত্তর পোস্ট করবেন না যা আপনার প্রশ্নের আপডেট মাত্র। পরিবর্তে আপনার প্রশ্ন সম্পাদনা করুন।
রায়ান স্টুয়ার্ট

দুঃখিত, আমি আপনার মন্তব্যটি লক্ষ্য করেছি! আপনার পরামর্শ অনুসারে আমি এটি ব্যবহার করে দেখাব এবং ফলাফলগুলি আপনাকে জানাব। আপনার সহায়তার জন্য ধন্যবাদ! ওহ, এবং আমি উত্তর দেওয়ার পরিবর্তে আমার প্রশ্নটি সম্পাদনা করার চেষ্টা করব ...
মেরিনা

7

ভবিষ্যতে যারা এই চেষ্টা করবে তাদের সকলের জন্য।

org.springframework.scheduling.quartz.JobDetailBean অবজেক্টের মানচিত্র সরবরাহ করে এবং সেই জিনিসগুলি বসন্ত মটরশুটি হতে পারে।

স্মিথের মতো সংজ্ঞা দিন

<bean name="myJobDetail" class="org.springframework.scheduling.quartz.JobDetailBean">
    <property name="jobClass"
        value="my.cool.class.myCoolJob" />
    <property name="jobDataAsMap">
        <map>
            <entry key="myBean" value-ref="myBean" />
        </map>
    </property>
</bean>

এবং তারপরে, ভিতরে

public void executeInternal(JobExecutionContext context)

কল myBean = (myBean) context.getMergedJobDataMap().get("myBean"); এবং আপনি সব সেট। আমি জানি, এটি দেখতে দেখতে কুৎসিত, তবে কাজের হিসাবে এটি কাজ করে


আইএমএইচও আমি এই সমাধানটি কোয়ার্টজ কাজের সাথে অটোয়ারিংয়ের সক্ষমতা যুক্ত করার চেষ্টা করার চেয়ে আরও পরিষ্কার এবং "প্রাকৃতিক" বোধ করি, সুতরাং আমার মনে হয় না এটি প্রায় কাজ।
সত্যই সুন্দর

6
ApplicationContext springContext =

WebApplicationContextUtils.getWebApplicationContext(ContextLoaderListener .getCurrentWebApplicationContext().getServletContext());

Bean bean = (Bean) springContext.getBean("beanName");

bean.method();

4

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

আমি অ্যাপ্লিকেশন কনটেক্সটস্চিডুলারকন্টেক্সটকে কী উল্লেখ না করেই পালিয়ে গেলাম - এটি আমার পক্ষে ছাড়া এটি কাজ করে।

অন্যের সুবিধার জন্য, এখানে চূড়ান্ত কনফিগারেশন যা আমার পক্ষে কাজ করেছে:

    <bean id="quartzScheduler"  class="org.springframework.scheduling.quartz.SchedulerFactoryBean">
        <property name="configLocation" value="classpath:spring/quartz.properties"/>
        <property name="jobFactory">
            <bean  class="org.springframework.scheduling.quartz.SpringBeanJobFactory" />
        </property>
        <property name="schedulerContextAsMap">
            <map>
                <entry key="mailService" value-ref="mailService" />
            </map>
        </property>
</bean>
<bean id="jobTriggerFactory"
      class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
    <property name="targetBeanName">
        <idref local="jobTrigger" />
    </property>
</bean>
<bean id="jobTrigger"   class="org.springframework.scheduling.quartz.SimpleTriggerBean"
    scope="prototype">
      <property name="group" value="myJobs" />
      <property name="description" value="myDescription" />
      <property name="repeatCount" value="0" />
</bean>

<bean id="jobDetailFactory"
      class="org.springframework.beans.factory.config.ObjectFactoryCreatingFactoryBean">
    <property name="targetBeanName">
        <idref local="jobDetail" />
    </property>
</bean>

<bean id="jobDetail" class="org.springframework.scheduling.quartz.JobDetailBean"
scope="prototype">
<property name="jobClass" value="com.cambridgedata.notifications.EMailJob" />
<property name="volatility" value="false" />
<property name="durability" value="false" />
<property name="requestsRecovery" value="true" />
</bean> 
<bean id="notificationScheduler"   class="com.cambridgedata.notifications.NotificationScheduler">
    <constructor-arg ref="quartzScheduler" />
    <constructor-arg ref="jobDetailFactory" />
    <constructor-arg ref="jobTriggerFactory" />
</bean>

লক্ষ্য করুন যে 'মেইল সার্ভিস' শিমটি আমার নিজস্ব পরিষেবা বিন, স্প্রিং দ্বারা পরিচালিত I আমি আমার কাজটিতে এটি নিম্নলিখিত হিসাবে অ্যাক্সেস করতে সক্ষম হয়েছি:

    public void executeInternal(JobExecutionContext context)
    throws JobExecutionException {

    logger.info("EMailJob started ...");
    ....
    SchedulerContext schedulerContext = null;
    try {
        schedulerContext = context.getScheduler().getContext();
    } catch (SchedulerException e1) {
        e1.printStackTrace();
    }
    MailService mailService = (MailService)schedulerContext.get("mailService");
    ....

এবং এই কনফিগারেশনটি কারখানাগুলি ব্যবহার করে ট্রিগার এবং জবডেটেলগুলি পেতে এবং সেগুলিগুলিতে প্রোগ্রামিকভাবে প্রয়োজনীয় পরামিতিগুলি সেট করে আমাকে গতিশীলভাবে কাজের সময়সূচী তৈরি করার অনুমতি দেয়:

    public NotificationScheduler(final Scheduler scheduler,
        final ObjectFactory<JobDetail> jobDetailFactory,
        final ObjectFactory<SimpleTrigger> jobTriggerFactory) {
    this.scheduler = scheduler;
    this.jobDetailFactory = jobDetailFactory;
    this.jobTriggerFactory = jobTriggerFactory;
           ...
        // create a trigger
        SimpleTrigger trigger = jobTriggerFactory.getObject();
        trigger.setRepeatInterval(0L);
    trigger.setStartTime(new Date());

    // create job details
    JobDetail emailJob = jobDetailFactory.getObject();

    emailJob.setName("new name");
    emailJob.setGroup("immediateEmailsGroup");
            ...

যারা আবার সাহায্য করেছেন তাদের সবাইকে আবার অনেক ধন্যবাদ,

মেরিনা


4

একটি সহজ সমাধান হ'ল জব ডেটা ম্যাপে বসন্ত শিম সেট করা এবং তারপরে চাকরী শ্রেণিতে শিমটি পুনরুদ্ধার করা, উদাহরণস্বরূপ

// the class sets the configures the MyJob class 
    SchedulerFactory sf = new StdSchedulerFactory();
    Scheduler sched = sf.getScheduler();
    Date startTime = DateBuilder.nextGivenSecondDate(null, 15);
    JobDetail job = newJob(MyJob.class).withIdentity("job1", "group1").build();
    job.getJobDataMap().put("processDataDAO", processDataDAO);

`

 // this is MyJob Class
    ProcessDataDAO processDataDAO = (ProcessDataDAO) jec.getMergedJobDataMap().get("processDataDAO");

কাজের ডেটা ব্লব হিসাবে সংরক্ষণ করা হয়েছে (ডিবি জেদ ব্যবহার করার সময়) বিবেচনা করে এটি ডিবি কর্মক্ষমতা সংক্রান্ত সমস্যার কারণ হতে পারে (কল্পনা করুন ডেটাটি সত্যই বিশাল)
সুদীপ ভান্ডারী

3

কোডটি কমপ্যামেন্টের সাথে দেখতে কেমন তা এখানে রয়েছে:

মূল শ্রেণি যা কাজের সময়সূচি দেয়:

public class NotificationScheduler {

private SchedulerFactory sf;
private Scheduler scheduler;

@PostConstruct
public void initNotificationScheduler() {
    try {
    sf = new StdSchedulerFactory("spring/quartz.properties");
    scheduler = sf.getScheduler();
    scheduler.start();
            // test out sending a notification at startup, prepare some parameters...
    this.scheduleImmediateNotificationJob(messageParameters, recipients);
        try {
            // wait 20 seconds to show jobs
            logger.info("sleeping...");
            Thread.sleep(40L * 1000L); 
            logger.info("finished sleeping");
           // executing...
        } catch (Exception ignore) {
        }

      } catch (SchedulerException e) {
    e.printStackTrace();
    throw new RuntimeException("NotificationScheduler failed to retrieve a Scheduler instance: ", e);
    }
}


public void scheduleImmediateNotificationJob(){
  try {
    JobKey jobKey = new JobKey("key");
    Date fireTime = DateBuilder.futureDate(delayInSeconds, IntervalUnit.SECOND);
    JobDetail emailJob = JobBuilder.newJob(EMailJob.class)
    .withIdentity(jobKey.toString(), "immediateEmailsGroup")
        .build();

    TriggerKey triggerKey = new TriggerKey("triggerKey");
    SimpleTrigger trigger = (SimpleTrigger) TriggerBuilder.newTrigger() 
        .withIdentity(triggerKey.toString(), "immediateEmailsGroup")
        .startAt(fireTime)
        .build();

    // schedule the job to run
    Date scheduleTime1 = scheduler.scheduleJob(emailJob, trigger);
  } catch (SchedulerException e) {
    logger.error("error scheduling job: " + e.getMessage(), e);
    e.printStackTrace();
      }
}

@PreDestroy
public void cleanup(){
    sf = null;
    try {
        scheduler.shutdown();
    } catch (SchedulerException e) {
        e.printStackTrace();
    }
}

ইমেলজবটি আমার প্রথম পোস্টের মতো @ সংস্থার টীকা বাদে একই রকম:

@Component
public class EMailJob implements Job { 
  @Autowired
  private JavaMailSenderImpl mailSenderImpl;
... }

এবং স্প্রিংয়ের কনফিগারেশন ফাইলটিতে রয়েছে:

...
<context:property-placeholder location="classpath:spring/*.properties" />
<context:spring-configured/>
<context:component-scan base-package="com.mybasepackage">
  <context:exclude-filter expression="org.springframework.stereotype.Controller"
        type="annotation" />
</context:component-scan>
<bean id="mailSenderImpl" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="${mail.host}"/>
    <property name="port" value="${mail.port}"/>
    ...
</bean>
<bean id="notificationScheduler" class="com.mybasepackage.notifications.NotificationScheduler">
</bean>

সব ধরনের সাহায্য করার জন্য ধন্যবাদ!

মেরিনা


আপনার অ্যাপটি শুরু হয়ে গেলে, আপনি কি আরম্ভ করা দেখছেন EmailJob? চেক করার একটি সহজ উপায় হল কনস্ট্রাক্টরে একটি লগ লাইন যুক্ত করা।
আতরেন

@ অ্যারন: হ্যাঁ, আমিও করি - তবে আমি যেমন আবিষ্কার করেছি, এটি দুটিবার শুরু করা হচ্ছে! একবার স্প্রিং ফ্রেমওয়ার্ক নিজেই (এবং আমি বাজি ধরছি যে মেল পরিষেবাটি এতে প্রবেশ করেছে ...) এবং তারপরে, কোয়ার্টজ নিজেই আরম্ভ করার পরে - ইমেলজব আবার কোয়ার্টজ কাঠামো দ্বারা আরম্ভ করা হচ্ছে - এবং এটিই এক এতে সার্ভিসটি ইনজেকশন দেওয়া নেই ... রায়ান যেমন পরামর্শ দিয়েছিলেন তেমন আমি আমার প্রশ্নটি সম্পাদনা করে বসন্তের শুরুতে একটি স্ট্যাক ট্রেস যুক্ত করার চেষ্টা করব ...
মেরিনা

2

হরিয়ার একটি সমাধান https://stackoverflow.com/a/37797575/4252764 খুব ভাল কাজ করে। এটি সহজ, এতগুলি বিশেষ কারখানার মটরশুটিগুলির প্রয়োজন নেই এবং একাধিক ট্রিগার এবং কাজগুলি সমর্থন করে। কেবল যুক্ত করুন যে কোয়ার্টজ কাজটি জেনেরিক হতে পারে, নির্দিষ্ট কাজগুলি নিয়মিত বসন্ত মটরশুটি হিসাবে প্রয়োগ করা হয়।

public interface BeanJob {
  void executeBeanJob();
}

public class GenericJob implements Job {

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    JobDataMap dataMap = context.getMergedJobDataMap();
    ((BeanJob)dataMap.get("beanJob")).executeBeanJob();    
  }

}

@Component
public class RealJob implements BeanJob {
  private SomeService service;

  @Autowired
  public RealJob(SomeService service) {
    this.service = service;
  }

  @Override
  public void executeBeanJob() {
      //do do job with service
  }

}

ধন্যবাদ আমিও তা বিবেচনা করেছি। তবে আমার ক্ষেত্রে, আমি একটি লাইব্রেরি লিখছিলাম যা কোনও কোয়ার্টজ বাস্তবায়নকে বিমূর্ত করে। এটি কোনও বস্তু পুনরুদ্ধার করতে 'কী' নামটি মনে রাখার জন্য প্রয়োজন। আমি এটি খাঁটি কোয়ার্টজ উপায়ে করতে সক্ষম হয়েছি এবং স্রেফ একটি উত্তর হিসাবে পোস্ট করেছি। প্লিজ আপনার চিন্তা ভাগ!
কার্তিক আর

2

এটি বেশ পুরানো পোস্ট যা এখনও কার্যকর। এই দুটি প্রস্তাব দেয় এমন সমস্ত সমাধানের মধ্যে খুব কম শর্ত ছিল যা সমস্ত স্যুট নয়:

  • SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this); এটি ধরে নেওয়া বা এটি একটি বসন্ত - ওয়েব ভিত্তিক প্রকল্প হতে হবে
  • AutowiringSpringBeanJobFactory পূর্ববর্তী উত্তরে উল্লিখিত ভিত্তিক পদ্ধতিটি খুব সহায়ক, তবে উত্তরটি তাদের জন্য নির্দিষ্ট যারা খাঁটি ভ্যানিলা কোয়ার্টজ এপি ব্যবহার করেন না বরং কোয়ার্টজকে একই কাজ করার জন্য স্প্রিংয়ের মোড়ক ব্যবহার করেন।

আপনি যদি নির্ধারণের জন্য খাঁটি কোয়ার্টজ বাস্তবায়নের সাথে থাকতে চান (স্প্রিংয়ের সাথে স্বতঃসংশ্লিষ্ট দক্ষতা সহ কোয়ার্টজ), আমি নীচে এটি করতে সক্ষম হয়েছি:

আমি এটি যতটা সম্ভব কোয়ার্টজ উপায়ে করতে খুঁজছিলাম এবং এইভাবে সামান্য হ্যাক সহায়ক হিসাবে প্রমাণিত।

 public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory{

    private AutowireCapableBeanFactory beanFactory;

    public AutowiringSpringBeanJobFactory(final ApplicationContext applicationContext){
        beanFactory = applicationContext.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        beanFactory.initializeBean(job, job.getClass().getName());
        return job;
    }
}


@Configuration
public class SchedulerConfig {   
    @Autowired private ApplicationContext applicationContext;

    @Bean
    public AutowiringSpringBeanJobFactory getAutowiringSpringBeanJobFactory(){
        return new AutowiringSpringBeanJobFactory(applicationContext);
    }
}


private void initializeAndStartScheduler(final Properties quartzProperties)
            throws SchedulerException {
        //schedulerFactory.initialize(quartzProperties);
        Scheduler quartzScheduler = schedulerFactory.getScheduler();

        //Below one is the key here. Use the spring autowire capable job factory and inject here
        quartzScheduler.setJobFactory(autowiringSpringBeanJobFactory);
        quartzScheduler.start();
    }

quartzScheduler.setJobFactory(autowiringSpringBeanJobFactory);আমাদের একটি স্বায়ত্তশাসিত কাজের উদাহরণ দেয়। যেহেতু AutowiringSpringBeanJobFactoryসুস্পষ্টভাবে একটি প্রয়োগ করে JobFactory, আমরা এখন একটি স্বয়ংক্রিয় তারের সমাধান সক্ষম করেছি। আশাকরি এটা সাহায্য করবে!


1

এটি করার একটি সহজ উপায় @Componentহ'ল কেবল টিকা দিয়ে কোয়ার্টজ জবসকে টীকায়িত করা এবং তারপরে স্প্রিং আপনার জন্য সমস্ত ডিআই ম্যাজিক করবে, কারণ এটি এখন একটি স্প্রিং শিম হিসাবে স্বীকৃত। একটি AspectJদিকের জন্য আমাকে অনুরূপ কিছু করতে হয়েছিল - আমি এটি স্প্রিং শিম ছিল না যতক্ষণ না আমি স্প্রিং @Componentস্টেরিওটাইপ দিয়ে এটিকে বর্ননা করি ।


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

আপনার EmailJobক্লাসটি কি কোনও প্যাকেজে রয়েছে যা অ্যাপ্লিকেশনটিতে স্প্রিং দ্বারা স্ক্যান করা হবে? আপনি যে ইনোটেকশন দিয়েছিলেন @Componentতবে ইনজেকশনের ক্লাসটি এখনও বাতিল তা এই ইঙ্গিত দেয় যে এটি স্ক্যান হচ্ছে না - অন্যথায় অ্যাপ্লিকেশন প্রারম্ভের ডিআই একটি ব্যতিক্রম ছুঁড়ে ফেলবে।
আতরিন

হারুন: হ্যাঁ, এটি স্ক্যান করার কথা - আমার কাছে <প্রসঙ্গ: উপাদান-স্ক্যান বেস-প্যাকেজ = "com.mybasepackage"> এটি করা উচিত ... আমার পরবর্তী উত্তরে আমি আমার মূলটির পুরো কোড সরবরাহ করছি ক্লাস, বসন্তের কনফিগারেশনের সাথে - ঠিক যদি কিছু স্পষ্টতই স্পট করা যায় ...
মেরিনা

"@ অটোভায়ার্ড" দিয়ে চিহ্নিত কাজের ক্ষেত্রগুলিকে ইনজেকশনের ব্যবস্থা করা হয় না এমনকি আপনি যদি "@ কমম্পোনেন্ট" দিয়ে কাজটি চিহ্নিত করেন
aloplop85

6
এটি কাজ করবে না কারণ জব অবজেক্ট তৈরি করা কোয়ার্ট দ্বারা পরিচালিত হয় এবং তাই ক্ষেত্রগুলি স্বতঃপ্রাপ্ত নয় এবং শ্রেণি টিকাগুলি অতিরিক্ত হ্যান্ডলিং ব্যতীত কিছুই করে না।
মিশানজেল

1

উপরের সমাধানটি দুর্দান্ত তবে আমার ক্ষেত্রে ইঞ্জেকশনটি কাজ করছে না। পরিবর্তে আমার অটোওয়্যারবিয়ানপ্রপার্টি ব্যবহার করা দরকার, সম্ভবত আমার প্রসঙ্গটি কনফিগার করা উপায়ের কারণে:

import org.quartz.spi.TriggerFiredBundle;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.scheduling.quartz.SpringBeanJobFactory;

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements
ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {
        beanFactory = context.getAutowireCapableBeanFactory();
    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
        final Object job = super.createJobInstance(bundle);
        //beanFactory.autowireBean(job);
        beanFactory.autowireBeanProperties(job, AutowireCapableBeanFactory.AUTOWIRE_BY_TYPE, true);
        return job;
    }
}

1

এটি সঠিক উত্তর http://stackoverflow.com/questions/6990767/inject-bean-references-into-a-quartz-job-in-spring/15211030#15211030 । এবং বেশিরভাগ লোকের জন্য কাজ করবে। তবে আপনার ওয়েব.এক্সএমএল যদি সমস্ত অ্যাপ্লিকেশন কনটেক্সট.এক্সএমএল ফাইল সম্পর্কে সচেতন না থাকে তবে কোয়ার্টজ জব সেই মটরশুটি চালাতে সক্ষম হবে না। অতিরিক্ত অ্যাপ্লিকেশনসন্টেক্সট ফাইলগুলি ইনজেক্ট করতে আমাকে একটি অতিরিক্ত স্তর করতে হয়েছিল

public class MYSpringBeanJobFactory extends SpringBeanJobFactory
        implements ApplicationContextAware {

    private transient AutowireCapableBeanFactory beanFactory;

    @Override
    public void setApplicationContext(final ApplicationContext context) {

        try {
                PathMatchingResourcePatternResolver pmrl = new PathMatchingResourcePatternResolver(context.getClassLoader());
                Resource[] resources = new Resource[0];
                GenericApplicationContext createdContext = null ;
                    resources = pmrl.getResources(
                            "classpath*:my-abc-integration-applicationContext.xml"
                    );

                    for (Resource r : resources) {
                        createdContext = new GenericApplicationContext(context);
                        XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(createdContext);
                        int i = reader.loadBeanDefinitions(r);
                    }

            createdContext.refresh();//important else you will get exceptions.
            beanFactory = createdContext.getAutowireCapableBeanFactory();

        } catch (IOException e) {
            e.printStackTrace();
        }



    }

    @Override
    protected Object createJobInstance(final TriggerFiredBundle bundle)
            throws Exception {
        final Object job = super.createJobInstance(bundle);
        beanFactory.autowireBean(job);
        return job;
    }
}

আপনি আপনার কোয়ার্টজ সচেতন হতে চান এমন যে কোনও প্রসঙ্গের ফাইল যুক্ত করতে পারেন।


0

আপনার নিশ্চিত করুন

AutowiringSpringBeanJobFactory extends SpringBeanJobFactory 

নির্ভরতা থেকে টানা হয়

    "org.springframework:spring-context-support:4..."

এবং না থেকে

    "org.springframework:spring-support:2..."

এটা আমি ব্যবহার করতে চেয়েছিলেন

@Override
public Job newJob(TriggerFiredBundle bundle, Scheduler scheduler)

পরিবর্তে

@Override
protected Object createJobInstance(final TriggerFiredBundle bundle)

তাই চাকরির উদাহরণ স্বরূপ দিতে ব্যর্থ হয়েছিল।


0

আপনি যদি ইতিমধ্যে আপনার প্রকল্পে সত্যিকারের AspectJ ব্যবহার করেন, তবে আপনি কাজের বীন শ্রেণীর সাথে বেনিফিট করতে পারেন @Configurable। তারপরে স্প্রিং এই ক্লাসে ইনজেকশন দেবে, এমনকি যদি এটির মাধ্যমে নির্মিত হয়new


0

আমি একই সমস্যাটির মুখোমুখি হয়েছি এবং নিম্নলিখিত পদ্ধতির সাথে এ থেকে বেরিয়েছি:

<!-- Quartz Job -->
<bean name="JobA" class="org.springframework.scheduling.quartz.JobDetailFactoryBean">
    <!-- <constructor-arg ref="dao.DAOFramework" /> -->
     <property name="jobDataAsMap">
    <map>
        <entry key="daoBean" value-ref="dao.DAOFramework" />
    </map>
</property>
    <property name="jobClass" value="com.stratasync.jobs.JobA" />
    <property name="durability" value="true"/>
</bean>

উপরের কোডে আমি জবাআ শিমের মধ্যে ডেও। ডিএএফ ফ্রেমওয়ার্ক সিম ইনজেকশান করি এবং এক্সিকিউটআইটার্নাল পদ্ধতিতে আপনি ইঞ্জিনযুক্ত শিমটি পেতে পারেন:

  daoFramework = (DAOFramework)context.getMergedJobDataMap().get("daoBean");

আমি আসা করি এটা সাহায্য করবে! ধন্যবাদ.


0

উপরের এই সমস্ত সমাধান আমার জন্য স্প্রিং 5 এবং হাইবারনেট 5 এবং কোয়ার্টজ 2.2.3 এর সাথে কাজ করে না যখন আমি লেনদেনের পদ্ধতিগুলি কল করতে চাই!

তাই আমি এই সমাধানটি কার্যকর করেছি যা স্বয়ংক্রিয়ভাবে সময়সূচী শুরু করে এবং কাজগুলি ট্রিগার করে। আমি dzoneপ্রচুর কোড পেয়েছি । কারণ গতিশীলভাবে আমার ট্রিগার এবং কাজ তৈরি করার দরকার নেই আমি চাইছিলাম স্থির ট্রিগারগুলি স্প্রিং কনফিগারেশনের মাধ্যমে সংজ্ঞায়িত করা উচিত এবং কেবলমাত্র কাজগুলি স্প্রিং উপাদান হিসাবে প্রকাশ করা উচিত।

আমার বেসিক কনফিগারেশনটি দেখতে এটির মতো

@Configuration
public class QuartzConfiguration {

  @Autowired
  ApplicationContext applicationContext;

  @Bean
  public SchedulerFactoryBean scheduler(@Autowired JobFactory jobFactory) throws IOException {
    SchedulerFactoryBean sfb = new SchedulerFactoryBean();

    sfb.setOverwriteExistingJobs(true);
    sfb.setAutoStartup(true);
    sfb.setJobFactory(jobFactory);

    Trigger[] triggers = new Trigger[] {
        cronTriggerTest().getObject()
    };
    sfb.setTriggers(triggers);
    return sfb;
  }

  @Bean
  public JobFactory cronJobFactory() {
    AutowiringSpringBeanJobFactory jobFactory = new AutowiringSpringBeanJobFactory();
    jobFactory.setApplicationContext(applicationContext);
    return jobFactory;
  }

  @Bean 
  public CronTriggerFactoryBean cronTriggerTest() {
    CronTriggerFactoryBean tfb = new CronTriggerFactoryBean();
    tfb.setCronExpression("0 * * ? * * *");

    JobDetail jobDetail = JobBuilder.newJob(CronTest.class)
                            .withIdentity("Testjob")
                            .build()
                            ;

    tfb.setJobDetail(jobDetail);
    return tfb;
  }

}

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

public final class AutowiringSpringBeanJobFactory extends SpringBeanJobFactory implements ApplicationContextAware {

  @Autowired
  private ApplicationContext applicationContext;

  private SchedulerContext schedulerContext;

  @Override
  public void setApplicationContext(final ApplicationContext context) {
    this.applicationContext = context;
  }


  @Override
  protected Object createJobInstance(final TriggerFiredBundle bundle) throws Exception {
    Job job = applicationContext.getBean(bundle.getJobDetail().getJobClass());
    BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(job);

    MutablePropertyValues pvs = new MutablePropertyValues();
    pvs.addPropertyValues(bundle.getJobDetail().getJobDataMap());
    pvs.addPropertyValues(bundle.getTrigger().getJobDataMap());

    if (this.schedulerContext != null)
    {
        pvs.addPropertyValues(this.schedulerContext);
    }
    bw.setPropertyValues(pvs, true);

    return job;
  }  

  public void setSchedulerContext(SchedulerContext schedulerContext) {
    this.schedulerContext = schedulerContext;
    super.setSchedulerContext(schedulerContext);
  }

}

এখানে আপনি আপনার স্বাভাবিক প্রয়োগের প্রসঙ্গ এবং আপনার কাজের সাথে একত্রে ওয়্যার করেন। এটি গুরুত্বপূর্ণ ব্যবধান কারণ সাধারণত কোয়ার্টজ এটির কর্মী থ্রেডগুলি শুরু করে যার সাথে আপনার আবেদনের প্রসঙ্গে কোনও সংযোগ নেই। আপনি লেনদেনের মেহটডগুলি কার্যকর করতে না পারার কারণ। হারিয়ে যাওয়া শেষ জিনিসটি একটি চাকরি is এটি দেখতে যেমন দেখতে পারেন

@Component
public class CronTest implements Job {

  @Autowired
  private MyService s;

  public CronTest() {
  }

  @Override
  public void execute(JobExecutionContext context) throws JobExecutionException {
    s.execute();
  }

}

এটি একটি নিখুঁত সমাধান নয় কারণ আপনি কেবল আপনার পরিষেবা পদ্ধতিতে কল করার জন্য একটি অতিরিক্ত শ্রেণি। তবে তবুও এটি কাজ করে।


0

জেডিবিসি চাকরির দোকান

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

এটি ঠিক করতে, ডিফল্ট ক্লাসলোডারটিকে কোয়ার্টজ বৈশিষ্ট্য ফাইলে এভাবে সেট করতে হবে:

org.quartz.scheduler.classLoadHelper.class=org.quartz.simpl.ThreadContextClassLoadHelper

রেফারেন্স হিসাবে: https://github.com/quartz-scheduler/quartz/issues/221


0

কেবল আপনার কাজটি বাড়িয়ে দিন QuartzJobBean

public class MyJob extends QuartzJobBean {

    @Autowired
    private SomeBean someBean;

    @Override
    protected void executeInternal(JobExecutionContext jobExecutionContext) throws JobExecutionException {
        System.out.println("Some bean is " + someBean.toString());
    }

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