如何获取spring ApplicationContext对象[spring总结]

本文参考 https://www.cnblogs.com/wangcp-2014/p/8126187.html 

ServletContextAware

 

ApplicationContext 是spring ioc容器,在这个容器中存储了bean对象实例(通过Map(ConcurrentHashMap)结构进行存储) 。 一般情况我们不会刻意去取ApplicationContext、WebApplicationContext这个对象,只是有时为了测试,需要从ioc容器中获取某个指定的Bean对象

 

一.  通过 xml文件方式、注解方式加载spring配置文件,启动spring ioc容器

xml方式: ClassPathXmlApplicationContext、FileSystemXmlApplicationContext —— 一个是从classpath路径下加载spring配置文件,另外一个是从指定的绝对路径下加载spring配置文件
注解方式: AnnotationConfigApplicationContext、AnnotationConfigWebApplicationContext —— 两者都是通过注解方式加载spring配置文件

示例如下: 


public class ProductWebApplication {


    private static ApplicationContext ac = null;

    public static void main(String[] args) {
        SpringApplication.run(ProductWebApplication.class, args);
        // 1.
        ApplicationContext ac1 = new ClassPathXmlApplicationContext("classpath:spring.xml");
        ProductComponentService bean1 = ac1.getBean("productComponentService", ProductComponentService.class);

        // 2.
        ApplicationContext ac2 = new FileSystemXmlApplicationContext("f:\\spring\\spring.xml");
        ProductComponentService bean2 = ac2.getBean("productComponentService", ProductComponentService.class);

        // 3.
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(WebConfig.class);
    //    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
        // ctx.register(WebConfig.class);
        // ctx.refresh();
        ProductComponentService bean3 = ctx.getBean("productComponentService", ProductComponentService.class);
        System.out.println(bean3.toString());

        // 4.
        AnnotationConfigWebApplicationContext acwc = new AnnotationConfigWebApplicationContext();
        acwc.register(WebConfig.class);
        acwc.refresh();
        ProductComponentService bean4 = acwc.getBean("productComponentService", ProductComponentService.class);
        System.out.println(bean4.toString());

    }
}
@Configuration
@EnableWebMvc
@ComponentScan(value= {"com.xxx.product.web"})
public class WebConfig extends WebMvcConfigurerAdapter {

}

二、 通过工具类WebApplicationContextUtils 来获取 


/**
 * 通过WebApplicationContextUtils工具类来获取 ApplicationContext对象
 */
class Demo {

    public static void main(String[] args) {

        ServletContext sc = null;

        // getRequiredWebApplicationContext 如果未获取到ac对象,会抛出异常
        ApplicationContext ac1 = WebApplicationContextUtils.getRequiredWebApplicationContext(sc);
        ProductComponentService productComponentService1 = ac1.getBean("productComponentService", ProductComponentService.class);

        // getWebApplicationContext 如果未获取到ac对象,返回null
        ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(sc);
        ProductComponentService productComponentService2 = ac2.getBean("productComponentService", ProductComponentService.class);

    }
}





	/**
	 * Find the root {@code WebApplicationContext} for this web app, typically
	 * loaded via {@link org.springframework.web.context.ContextLoaderListener}.
	 * 

Will rethrow an exception that happened on root context startup, * to differentiate between a failed context startup and no context at all. * @param sc ServletContext to find the web application context for * @return the root WebApplicationContext for this web app, or {@code null} if none * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE */

但是通过WebApplicationContextUtils 工具类获取 ioc容器的时候,不能在容器启动的时候 ( root context startup),否则会抛出异常,看WebApplicationContextUtils的 方法注释就知道了


    /**
     * Find the root {@code WebApplicationContext} for this web app, typically
     * loaded via {@link org.springframework.web.context.ContextLoaderListener}.
     *

Will rethrow an exception that happened on root context startup,
     * to differentiate between a failed context startup and no context at all.
     * @param sc ServletContext to find the web application context for
     * @return the root WebApplicationContext for this web app, or {@code null} if none
     * @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
     */

 

三、继承方式:

3.1 继承  ApplicationObjectSupport ( abstract class  ) 

它实现了 ApplicationContextAware 接口

public abstract class ApplicationObjectSupport implements ApplicationContextAware {}

说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext 
Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。

 

spring mvn 4.3.12  AbstractDetectingUrlHandlerMapping.java 类就有获取 ioc容器的应用,并且是通过继承ApplicationObjectSupport 的方式

AbstractDetectingUrlHandlerMapping中的 detectHandlers()方法

如何获取spring ApplicationContext对象[spring总结]_第1张图片

 

如何获取spring ApplicationContext对象[spring总结]_第2张图片

ApplicationObjectSupport类图关系

 

 

3.2  继承WebApplicationObjectSupport  (abstract class)

它继承自上面的ApplicationObjectSupport类


public abstract class WebApplicationObjectSupport extends ApplicationObjectSupport implements ServletContextAware {

说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext
 

 

如何获取spring ApplicationContext对象[spring总结]_第3张图片

WebApplicationObjectSupport类图关系, 他还实现了 ServletContextAware接口,也就是可以获取到 ServletContext信息

 

 

 

四、 实现 ApplicationContextAware  接口

和这个  ApplicationContextAware接口 类似的有 ServletContextAware 

ServletContextAware 中可以获取到Servlet容器信息 

这种 XxxAware接口是spring的一种特性,扩展,在spring容器启动的时候,只要实现了这种Aware接口[有一个Aware接口],都是被spring容器进行回调,类似的还有:

BeanFactoryAware
BeanNameAware
... ... 

@SpringBootApplication
@MapperScan("com.xxx.mapper") // 扫描mybatis mapper文件
public class Application implements ApplicationContextAware {

	private static ApplicationContext ac = null;

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);

        // ac 成员变量在spring 容器启动的时候,进行了初始化赋值,可以直接使用该成员变量了,从spring ioc容器中获取bean对象
		ProductComponentService productComponentService = ac.getBean("xxx", ProductComponentService.class);
		productComponentService.doXXX();
	}


    // 因为实现了ApplicationContextAware接口,所以本方法在spring容器启动的时候会调用,并注入 applicationContext
	@Override
	public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
		ac = applicationContext;
	}
}

实现Aware接口的还有很多:

如何获取spring ApplicationContext对象[spring总结]_第4张图片

 

五、 据说还有一种方式,通过获取当前线程对应的 WebApplicationContext对象, 没试过 这种方式。

 public static void main(String[] args) {
        // 获取当前线程,对应的WebApplicationContext对象

        WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
        ProductComponentService productComponentService3 = wac.getBean("productComponentService", ProductComponentService.class);


    }

 

你可能感兴趣的:(spring,spring,4,java,ioc)