001/*
002 * Copyright 2002-2017 the original author or authors.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *      https://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.springframework.scheduling.quartz;
018
019import org.quartz.Scheduler;
020import org.quartz.SchedulerException;
021import org.quartz.impl.SchedulerRepository;
022
023import org.springframework.beans.factory.BeanFactory;
024import org.springframework.beans.factory.BeanFactoryAware;
025import org.springframework.beans.factory.InitializingBean;
026import org.springframework.beans.factory.ListableBeanFactory;
027import org.springframework.lang.Nullable;
028import org.springframework.util.Assert;
029
030/**
031 * Spring bean-style class for accessing a Quartz Scheduler, i.e. for registering jobs,
032 * triggers and listeners on a given {@link org.quartz.Scheduler} instance.
033 *
034 * <p>Compatible with Quartz 2.1.4 and higher, as of Spring 4.1.
035 *
036 * @author Juergen Hoeller
037 * @since 2.5.6
038 * @see #setScheduler
039 * @see #setSchedulerName
040 */
041public class SchedulerAccessorBean extends SchedulerAccessor implements BeanFactoryAware, InitializingBean {
042
043        @Nullable
044        private String schedulerName;
045
046        @Nullable
047        private Scheduler scheduler;
048
049        @Nullable
050        private BeanFactory beanFactory;
051
052
053        /**
054         * Specify the Quartz {@link Scheduler} to operate on via its scheduler name in the Spring
055         * application context or also in the Quartz {@link org.quartz.impl.SchedulerRepository}.
056         * <p>Schedulers can be registered in the repository through custom bootstrapping,
057         * e.g. via the {@link org.quartz.impl.StdSchedulerFactory} or
058         * {@link org.quartz.impl.DirectSchedulerFactory} factory classes.
059         * However, in general, it's preferable to use Spring's {@link SchedulerFactoryBean}
060         * which includes the job/trigger/listener capabilities of this accessor as well.
061         * <p>If not specified, this accessor will try to retrieve a default {@link Scheduler}
062         * bean from the containing application context.
063         */
064        public void setSchedulerName(String schedulerName) {
065                this.schedulerName = schedulerName;
066        }
067
068        /**
069         * Specify the Quartz {@link Scheduler} instance to operate on.
070         * <p>If not specified, this accessor will try to retrieve a default {@link Scheduler}
071         * bean from the containing application context.
072         */
073        public void setScheduler(Scheduler scheduler) {
074                this.scheduler = scheduler;
075        }
076
077        /**
078         * Return the Quartz Scheduler instance that this accessor operates on.
079         */
080        @Override
081        public Scheduler getScheduler() {
082                Assert.state(this.scheduler != null, "No Scheduler set");
083                return this.scheduler;
084        }
085
086        @Override
087        public void setBeanFactory(BeanFactory beanFactory) {
088                this.beanFactory = beanFactory;
089        }
090
091
092        @Override
093        public void afterPropertiesSet() throws SchedulerException {
094                if (this.scheduler == null) {
095                        this.scheduler = (this.schedulerName != null ? findScheduler(this.schedulerName) : findDefaultScheduler());
096                }
097                registerListeners();
098                registerJobsAndTriggers();
099        }
100
101        protected Scheduler findScheduler(String schedulerName) throws SchedulerException {
102                if (this.beanFactory instanceof ListableBeanFactory) {
103                        ListableBeanFactory lbf = (ListableBeanFactory) this.beanFactory;
104                        String[] beanNames = lbf.getBeanNamesForType(Scheduler.class);
105                        for (String beanName : beanNames) {
106                                Scheduler schedulerBean = (Scheduler) lbf.getBean(beanName);
107                                if (schedulerName.equals(schedulerBean.getSchedulerName())) {
108                                        return schedulerBean;
109                                }
110                        }
111                }
112                Scheduler schedulerInRepo = SchedulerRepository.getInstance().lookup(schedulerName);
113                if (schedulerInRepo == null) {
114                        throw new IllegalStateException("No Scheduler named '" + schedulerName + "' found");
115                }
116                return schedulerInRepo;
117        }
118
119        protected Scheduler findDefaultScheduler() {
120                if (this.beanFactory != null) {
121                        return this.beanFactory.getBean(Scheduler.class);
122                }
123                else {
124                        throw new IllegalStateException(
125                                        "No Scheduler specified, and cannot find a default Scheduler without a BeanFactory");
126                }
127        }
128
129}