【Spring】非Spring IOC容器下获取Spring IOC上下文的环境

前言

在Spring Web项目中,有些特殊的时候需要在非Spring IOC容器下获取Spring IOC容器的上下文环境,比如获取某个bean。

版本说明

声明POM文件,指定需引入的JAR。

<properties>
        <spring.version>4.0.9.RELEASE</spring.version>
	</properties>

	<dependencies>

		<dependency>
			<groupId>javax.servlet</groupId>
			<artifactId>javax.servlet-api</artifactId>
			<version>3.1.0</version>
		</dependency>
		
		<dependency>
			<groupId>org.springframework.webflow</groupId>
			<artifactId>spring-webflow</artifactId>
			<version>2.3.4.RELEASE</version>
		</dependency>

	</dependencies>

实现ApplicationContectAware

写一个工具类实现ApplicationContectAware,然后在配置文件注册它。需要实现ApplicationContectAware的一个抽象方法setApplicationContect(),容器会调用此方法设置上下文对象ApplicationContext

package util;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

public class ApplicationContextUtil implements ApplicationContextAware {
    
	private static ApplicationContext applicationContext;

	public void setApplicationContext(ApplicationContext ac)
			throws BeansException {
		applicationContext = ac;
	}

	public static ApplicationContext getApplicationContext() {
		return applicationContext;
	}
	
	/**
	 * 根据Class类型在IOC容器中获取对象
	 * @param clazz Class类型
	 * @return 对象
	 */
	public static <T> List<T> getBeanByType(Class<T> clazz) {
		List<T> list = new ArrayList<T>();
		
		/* 获取接口的所有实例名 */
		String[] beanNames = applicationContext.getBeanNamesForType(clazz);
		System.out.println("getBeanByType beanNames : " + beanNames == null ? "" : Arrays.toString(beanNames));
		
		if (beanNames == null || beanNames.length == 0) {
			return list;
		}
		
		T t = null;
		for (String beanName : beanNames) {
			t = (T)applicationContext.getBean(beanName);
			list.add(t);
		}
		
		return list;
	}

}
<bean class="util.ApplicationContextUtil" />

非Spring IOC容器内,访问Spring IOC容器的环境

此UserService并无注解为@Service或@Component,它并非Spring IOC容器下管理的,使用它的类可能是通过new关键字实例化的。
EspecialBusinessService是一个接口,MyEspecialBusinessService1和MyEspecialBusinessService2实现该接口,并注解为@Service。
以下例子尝试获取单个bean和实现EspecialBusinessService接口的一组bean。

package service;

import java.util.List;

import util.ApplicationContextUtil;

public class UserService {
    
	public void update() {
		MyEspecialBusinessService2 service2 = ApplicationContextUtil.getApplicationContext().getBean(MyEspecialBusinessService2.class);
		System.out.println("service2 : " + service2);
		
		List<EspecialBusinessService> serviceList = ApplicationContextUtil.getBeanByType(EspecialBusinessService.class);
		System.out.println("getBeanByType(EspecialBusinessService.class) : " + serviceList);
	}
	
}

posted @ 2017-01-03 13:33  nick_huang  阅读(1565)  评论(0编辑  收藏  举报