package com.face.util;

import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.OrderComparator;
import org.springframework.core.env.Environment;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * Spring上下文工具类，用以让普通类获取Spring容器中的Bean
 *
 * @author leo
 */
public class SpringUtil implements ApplicationContextInitializer {

    private static ApplicationContext applicationContext = null;

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

    @Override
    public void initialize(ConfigurableApplicationContext applicationContext) {

        SpringUtil.applicationContext = applicationContext;
    }

    public static Environment getEnvironment() {
        return getApplicationContext().getEnvironment();
    }

    public static String getApplicationName() {
        return getEnvironment().getProperty("spring.application.name");
    }

    /**
     * 获取Class<?>的实现类实例Bean
     *
     * @param clazz
     * @return
     */
    public static Map<String, ?> getBeanOfType(Class<?> clazz) {
        return getApplicationContext().getBeansOfType(clazz);
    }

    /**
     * 根据orderedr接口获取Class<?>的实现类实例Bean
     *
     * @param clazz
     * @return
     */
    public static <T> List<T> getBeansListOfTypeWithOrder(Class<T> clazz) {
        Map<String, T> beansOfType = getApplicationContext().getBeansOfType(clazz, true, true);
        return beansOfType.values().stream().sorted(new OrderComparator()).collect(Collectors.toList());
    }

    public static <T> Collection<T> getBeansList(Class<T> clazz) {
        return getApplicationContext().getBeansOfType(clazz, true, true).values();
    }

    /**
     * 获取 Bean
     *
     * @param clazz
     * @return
     */
    public static <T> T getBean(Class<T> clazz) {
        return getApplicationContext().getBean(clazz);
    }

    /**
     * 全类名获取 Bean
     *
     * @param clazz
     * @return
     */
    public static Object getBeanByPath(Class<?> clazz) {
        return getApplicationContext().getBean(clazz.getName());
    }

    /**
     * 获取 Bean
     *
     * @param beanId
     * @return
     */
    public static Object getBean(String beanId) {
        return getApplicationContext().getBean(beanId);
    }

}
