/* * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package demo.lifecycle; import java.lang.reflect.Method; import java.util.concurrent.atomic.AtomicBoolean; import org.springframework.aop.support.AopUtils; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.BeanPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.SmartLifecycle; import org.springframework.core.Ordered; import org.springframework.core.annotation.AnnotationUtils; import org.springframework.stereotype.Component; import org.springframework.util.ReflectionUtils; import org.springframework.util.ReflectionUtils.MethodCallback; /** * @author Dave Syer * */ @Component public class SmartLifecycleRegistry implements BeanFactoryAware, BeanPostProcessor { private ConfigurableListableBeanFactory beanFactory; @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = (ConfigurableListableBeanFactory) beanFactory; } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { Class<?> targetClass = AopUtils.getTargetClass(bean); ReflectionUtils.doWithMethods(targetClass, new MethodCallback() { @Override public void doWith(Method method) throws IllegalArgumentException, IllegalAccessException { Start start = AnnotationUtils.getAnnotation(method, Start.class); if (start != null) { processStart(beanName, start, method, bean); } } }); return bean; } protected void processStart(String beanName, Start start, Method method, Object bean) { beanFactory.registerSingleton("lifecycle." + beanName, new SmartLifecycleWrapper( start.phase(), start.order(), start.autoStart(), bean, method)); } private static class SmartLifecycleWrapper implements SmartLifecycle, Ordered { private int phase; private int order; private boolean autoStart; private Object bean; private Method method; private AtomicBoolean running = new AtomicBoolean(false); public SmartLifecycleWrapper(int phase, int order, boolean autoStart, Object bean, Method method) { this.phase = phase; this.order = order; this.autoStart = autoStart; this.bean = bean; this.method = method; } @Override public int getOrder() { return order; } @Override public void start() { if (running.compareAndSet(false, true)) { ReflectionUtils.invokeMethod(method, bean); } } @Override public void stop() { if (running.compareAndSet(true, false)) { } } @Override public boolean isRunning() { return running.get(); } @Override public int getPhase() { return phase; } @Override public boolean isAutoStartup() { return autoStart; } @Override public void stop(Runnable callback) { if (running.compareAndSet(true, false)) { callback.run(); } } } }