package cn.superdesk.uniorder.common.spring;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * 这个实际上是没什么作用的
 * 关于XxxAware不展开了
 * 普通类调用Spring bean对象:
 * 说明:
 * 1、此类需要放到App.java同包或者子包下才能被扫描,否则失效。
 */
@Slf4j
@Component
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

	private static ApplicationContext applicationContext = null;

	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

		if (SpringContextHolder.applicationContext == null) {
			SpringContextHolder.applicationContext = applicationContext;
		}

		log.info(
				"\n------------------------------------------------------------------------------------------------------------------------------------------" +
				"\n------------------------------------cn.superdesk.uniorder.utils.SpringContextHolder-------------------------------------------------------" +
				"\nApplicationContext配置成功," +
				"\n普通类可以通过调用 SpringContextHolder.getAppContext()获取applicationContext对象" +
				"\napplicationContext={} -" +
				"\n------------------------------------------------------------------------------------------------------------------------------------------",
				SpringContextHolder.applicationContext);
	}

	/**
	 * 获取 applicationContext
	 * 屏蔽
	 *
	 * @return
	 */
//	public static ApplicationContext getApplicationContext() {
//		return applicationContext;
//	}

	/**
	 * 检查 ApplicationContext 不为空.
	 */
	private static void assertContextInjected() {
		if (applicationContext == null) {
			throw new IllegalStateException("applicaitonContext属性未注入, 请在applicationContext" +
					".xml中定义SpringContextHolder或在SpringBoot启动类中注册SpringContextHolder.");
		}
	}

	/**
	 * 清除 SpringContextHolder 中的 ApplicationContext 为 Null.
	 */
	private static void clearHolder() {
		log.debug("清除SpringContextHolder中的ApplicationContext:"
				+ applicationContext);
		applicationContext = null;
	}

	@Override
	public void destroy() {
		SpringContextHolder.clearHolder();
	}

	/**
	 * 通过name获取 Bean.
	 *
	 * @param name
	 * @return
	 */
	public static Object getBean(String name) {
		assertContextInjected();
		return applicationContext.getBean(name);

	}

	/**
	 * 从静态变量 applicationContext 中取得Bean, 自动转型为所赋值对象的类型.
	 *
	 * @param clazz
	 * @param <T>
	 * @return
	 */
	public static <T> T getBean(Class<T> clazz) {
		assertContextInjected();
		return (T) applicationContext.getBean(clazz);
	}

	/**
	 * 通过name,以及Clazz返回指定的Bean
	 */
	public static <T> T getBean(String name, Class<T> clazz) {
		assertContextInjected();
		return (T) applicationContext.getBean(name, clazz);
	}

}
