001/*
002 * Copyright 2012-2018 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 *      http://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.boot.devtools.restart;
018
019import org.apache.commons.logging.Log;
020import org.apache.commons.logging.LogFactory;
021
022import org.springframework.boot.context.event.ApplicationFailedEvent;
023import org.springframework.boot.context.event.ApplicationPreparedEvent;
024import org.springframework.boot.context.event.ApplicationReadyEvent;
025import org.springframework.boot.context.event.ApplicationStartingEvent;
026import org.springframework.context.ApplicationEvent;
027import org.springframework.context.ApplicationListener;
028import org.springframework.core.Ordered;
029
030/**
031 * {@link ApplicationListener} to initialize the {@link Restarter}.
032 *
033 * @author Phillip Webb
034 * @author Andy Wilkinson
035 * @since 1.3.0
036 * @see Restarter
037 */
038public class RestartApplicationListener
039                implements ApplicationListener<ApplicationEvent>, Ordered {
040
041        private static final String ENABLED_PROPERTY = "spring.devtools.restart.enabled";
042
043        private static final Log logger = LogFactory.getLog(RestartApplicationListener.class);
044
045        private int order = HIGHEST_PRECEDENCE;
046
047        @Override
048        public void onApplicationEvent(ApplicationEvent event) {
049                if (event instanceof ApplicationStartingEvent) {
050                        onApplicationStartingEvent((ApplicationStartingEvent) event);
051                }
052                if (event instanceof ApplicationPreparedEvent) {
053                        onApplicationPreparedEvent((ApplicationPreparedEvent) event);
054                }
055                if (event instanceof ApplicationReadyEvent
056                                || event instanceof ApplicationFailedEvent) {
057                        Restarter.getInstance().finish();
058                }
059                if (event instanceof ApplicationFailedEvent) {
060                        onApplicationFailedEvent((ApplicationFailedEvent) event);
061                }
062        }
063
064        private void onApplicationStartingEvent(ApplicationStartingEvent event) {
065                // It's too early to use the Spring environment but we should still allow
066                // users to disable restart using a System property.
067                String enabled = System.getProperty(ENABLED_PROPERTY);
068                if (enabled == null || Boolean.parseBoolean(enabled)) {
069                        String[] args = event.getArgs();
070                        DefaultRestartInitializer initializer = new DefaultRestartInitializer();
071                        boolean restartOnInitialize = !AgentReloader.isActive();
072                        if (!restartOnInitialize) {
073                                logger.info(
074                                                "Restart disabled due to an agent-based reloader being active");
075                        }
076                        Restarter.initialize(args, false, initializer, restartOnInitialize);
077                }
078                else {
079                        logger.info("Restart disabled due to System property '" + ENABLED_PROPERTY
080                                        + "' being set to false");
081                        Restarter.disable();
082                }
083        }
084
085        private void onApplicationPreparedEvent(ApplicationPreparedEvent event) {
086                Restarter.getInstance().prepare(event.getApplicationContext());
087        }
088
089        private void onApplicationFailedEvent(ApplicationFailedEvent event) {
090                Restarter.getInstance().remove(event.getApplicationContext());
091        }
092
093        @Override
094        public int getOrder() {
095                return this.order;
096        }
097
098        /**
099         * Set the order of the listener.
100         * @param order the order of the listener
101         */
102        public void setOrder(int order) {
103                this.order = order;
104        }
105
106}