工具类------让普通类能够获取ApplicationContext和Spring容器中的bean和配置项

       在编写Web代码时,可能需要让工具类或者是没有加入到Spring bean工厂的类,能够访问到Spring中的ApplicationContext和、bean和配置项,这时,因为该类没有加入到Spring容器中,所以不能在这个类中使用@Autowired来注入Spring中的bean,这时就需要一个工具类,来完成这件事。

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

import javax.servlet.ServletContext;
import java.util.Collections;
import java.util.Map;

@Configuration
public class ApplicationContextExt implements ApplicationContextAware {
    private static ApplicationContext context = null;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        ApplicationContextExt.context = applicationContext;
    }

    /**
     * 取得存储在静态变量中的ApplicationContext.
     */
    public static ApplicationContext getContext() {
        if (context == null)
            throw new IllegalStateException("can not found application context.");
        return context;
    }

    /**
     * 从静态变量ApplicationContext中取得Bean, 自动转型为所赋值对象的类型
     */
    @SuppressWarnings("unchecked")
    public static  T getBean(String name) {
        if (context == null)
            throw new IllegalStateException("can not find application context.");
        try {
            return (T) context.getBean(name);
        } catch (BeansException e) {

        }
        return (T) null;
    }

    @SuppressWarnings("unchecked")
    public static  T getBean(String name, ServletContext sc) {
        if (sc == null)
            throw new IllegalStateException("can not find servlet context.");
        try {
            return (T) WebApplicationContextUtils.getWebApplicationContext(sc).getBean(name);
        } catch (BeansException e) {

        }
        return (T) null;
    }


    public static  T getBean(Class cls) {
        if (context == null)
            throw new IllegalStateException("can not find application context.");
        try {
            return (T) context.getBean(cls);
        } catch (BeansException e) {

        }
        return (T) null;
    }

    public static  T getBean(Class cls, ServletContext sc) {
        if (sc == null)
            throw new IllegalStateException("can not find servlet context.");
        try {
            return (T) WebApplicationContextUtils.getWebApplicationContext(sc).getBean(cls);
        } catch (BeansException e) {

        }
        return (T) null;
    }

    public static  Map getBeansOfType(Class cls) {
        if (context == null)
            throw new IllegalStateException("can not found application context.");
        try {
            return context.getBeansOfType(cls);
        } catch (BeansException e) {

        }
        return Collections.emptyMap();
    }

    public static  Map getBeansOfType(Class cls, ServletContext sc) {
        if (sc == null) {
            throw new IllegalStateException("can not find servlet context.");
        }
        try {
            return WebApplicationContextUtils.getWebApplicationContext(sc).getBeansOfType(cls);
        } catch (BeansException e) {
            // TODO: handle exception
        }
        return Collections.emptyMap();
    }

    /**
     * 根据WebApp的虚拟路径获取文件的绝对路径
     *
     * @param path
     * @return
     */
    public static String getAbsolutePathInWeb(String path) {
        return ((WebApplicationContext) context).getServletContext().getRealPath(path);
    }

    public static Resource getResource(String location) {
        return context.getResource(location);
    }

}

        ApplicationContextExt类添加了@Configuration注解,所以ApplicationContextExt会在Spring初始化bean的时候被创建,而且实现了ApplicationContextAware接口,spring会在创建bean时,调用bean的生命周期函数,其中ApplicationContextAware接口的setApplicationContext就是bean的生命周期函数的一个。关于Spring中bean的生命周期,可以查看:Spring中bean的生命周期(最详细),注意:如果该类没有标注@Configuration注解,Spring是不会将你加载成一个bean的,也就没有调用这个bean的生命周期函数这个说法。

         ApplicationContextExt类的核心关键是获取了Spring容器,所以Spring容器里面有的,都可以获取到,这里只写出了获取bean和resource的方法,也可以自行添加其他方法。

        因为该ApplicationContextExt不是bean后置处理器和bean 工厂的后置处理器,所以不能保证其他bean使用之前被创建完成,只有后置处理器在注册时可以指定先后顺序,而普通的bean我在源码中没有看到注册bean有先后顺序,普通bean只能保存它依赖的bean先被注册,而此时我们使用的是工具类,在普通bean中,没有使用@Autowired来指定依赖这个bean,所以这个工具类被使用的时机,应该是Spring容器完成初始化bean之后,再进行使用,这一点要注册。

       Spring容器完成初始化bean之后,容器还能干什么用?编写服务器端代码,用户发送的请求,都是在Spring容器完成初始化bean之后,才能进行请求,所以,用户的接口都是可以使用这个工具类的。

你可能感兴趣的:(Spring,项目实用)