Spring容器和编写获取Spring上下文的工具类

Spring有两个核心接口:BeanFactory和ApplicationContext,其中ApplicationContext是BeanFactory的子接口。他们都可代表Spring容器,Spring容器是生成Bean实例的工厂,并且管理容器中的Bean。

Bean是Spring管理的基本单位,在基于Spring的Java EE应用中,所有的组件都被当成Bean处理,包括数据源、Hibernate的SessionFactory、事务管理器等。在Spring中,Bean的是一个非常广义的概念,任何的Java对象、Java组件都被当成Bean处理。

而且应用中的所有组件,都处于Spring的管理下,都被Spring以Bean的方式管理,Spring负责创建Bean实例,并管理他们的生命周期。Bean在Spring容器中运行,无须感受Spring容器的存在,一样可以接受Spring的依赖注入,包括Bean属性的注入,协作者的注入、依赖关系的注入等。

Spring容器负责创建Bean实例,所以需要知道每个Bean的实现类,Java程序面向接口编程,无须关心Bean实例的实现类;但是Spring容器必须能够精确知道每个Bean实例的实现类,因此Spring配置文件必须精确配置Bean实例的实现类。

一、Spring容器

Spring容器最基本的接口就是BeanFactor。BeanFactory负责配置、创建、管理Bean,他有一个子接口:ApplicationContext,因此也称之为Spring上下文。Spring容器负责管理Bean与Bean之间的依赖关系。

BeanFactory接口包含以下几个基本方法:

 Ø Boolean containBean(String name):判断Spring容器是否包含id为name的Bean实例。

 Ø <T> getBean(Class<T> requiredTypr):获取Spring容器中属于requiredType类型的唯一的Bean实例。

 Ø Object getBean(String name):返回Sprin容器中id为name的Bean实例。

 Ø <T> T getBean(String name,Class requiredType):返回容器中id为name,并且类型为requiredType的Bean

 Ø Class <?> getType(String name):返回容器中指定Bean实例的类型。

调用者只需使用getBean()方法即可获得指定Bean的引用,无须关心Bean的实例化过程。即Bean实例的创建过程完全透明。

在使用BeanFactory接口时,我们一般都是使用这个实现类:org.springframework.beans.factory.xml.XmlBeanFactory。然而ApplicationContext作为BeanFactory的子接口,使用它作为Spring容器会更加方便。它的实现类有:FileSystemXmlApplicationContext、ClassPathXmlApplicationContext、AnnotationConfigApplicationContext。

创建Spring容器实例时,必须提供Spring容器管理的Bean的详细配置信息。Spring的配置信息通常采用xml配置文件来设置,因此,创建BeanFactory实例时,应该提供XML配置文件作为参数。
web.xml中的配置:

<!--设置Spring的配置文件启动路径 -->
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>classpath:conf/app-context.xml</param-value>
</context-param>
<!-- Spring启动监听器 -->
<listener>
	<listener-class>com.hnjl.core.web.listener.StartupListner</listener-class>
</listener>

在这里我们首先讲解下web项目启动的加载顺序:
以Tomcat举例,启动Tomcat之后,首先会加载web.xml文件:

1、容器首先读取web.xml中的的配置内容和标签中配置项;

2、紧接着实例化ServletContext对象,并将配置的内容转化为键值传递给ServletContext;

3、创建配置的监听器的类实例,并且启动监听;

4、调用listener的contextInitialized(ServletContextEvent args)方法,ServletContext= ServletContextEvent.getServletContext();
此时你可以通过ServletContext获取context-param配置的内容并可以加以修改,此时Tomcat还没完全启动完成。

5、后续加载配置的各类filter;

6、最后加载servlet;

最后的结论是:web.xml中配置项的加载顺序是context-param=>listener=>filter=>servlet,配置项的顺序并不会改变加载顺序,但是同类型的配置项会应该加载顺序,servlet中也可以通过load-on-startup来指定加载顺序

接下来创建一个自己的工具类(AppUtil)实现Spring的ApplicationContextAware接口。最后在Spring配置文件中注册你的工具类。配置如下:

<!-- spring上下文,可以获取 上下文的Context -->
<bean id="appUtil" class="com.hnjl.core.util.AppUtil" />

AppUtil的实现代码:

/**
 * 获取ApplicationContext, 调用方法 AppUtil.getContext();<br>
 * 在spring文件中配置方法:<br>
 * <bean id="AppUtil" class="com.hnjl.core.util.AppUtil" />
 * @author hnjl
 *
 */
public class AppUtil implements ApplicationContextAware {

	private static  ApplicationContext applicationContext;
	
	
	
	/**
	 * 在线用户
	 */
	private static Map<Long,OnlineUser> onlineUsers=new LinkedHashMap<Long, OnlineUser>();
	
	
	private static ServletContext servletContext;
	
	
	/**
	 * 
	 * @param servletContext
	 */
	public static void init(ServletContext _servletContext)
	{
		servletContext=_servletContext;
	}
	
	/**
	 * 获取web应用的ServletContext对象。
	 * @return
	 * @throws Exception
	 */
	public static ServletContext getServletContext() throws Exception{
		return servletContext;
	}

	/**
	 * spring启动时注入context
	 */
	public void setApplicationContext(ApplicationContext contex) throws BeansException {
		applicationContext=contex;
	}

	/**
	 * 获取spring的上下文。
	 * @return
	 */
	public static ApplicationContext getContext(){
		return applicationContext;
	}
	
	
	public static List<Class> getImplClass(Class clazz) throws ClassNotFoundException{
		List<Class> list=new ArrayList<Class>();
		
		Map map= applicationContext.getBeansOfType(clazz);
		for(Object obj : map.values()){
			String name=obj.getClass().getName();
			int pos=name.indexOf("$$");
			if(pos>0){
				name=name.substring(0,name.indexOf("$$")) ; 
			}
			Class cls= Class.forName(name);
			
			list.add(cls);
		}
		return list;
	}
	
	

	
	/**
	 * 根据类从spring上下文获取bean。
	 * @param cls
	 * @return
	 */
	public  static <C> C getBean(Class<C> cls){
		return applicationContext.getBean(cls);
	}
	
	/**
	 * 根据类名从spring上下文获取bean。
	 * @param cls
	 * @return
	 */
	public static Object getBean(String  beanId){
		return applicationContext.getBean(beanId);
	}

	/**
	 * 取得应用程序的绝对路径
	 * @return
	 */
	public static String getAppAbsolutePath(){
		return servletContext.getRealPath("/");
	}
	
	/**
	 * 在web环境中根据web页面的路径获取对应页面的绝对路径。
	 * @param path
	 * @return
	 */
	public static String getRealPath(String path){
		return servletContext.getRealPath(path);
	}
	
	public static Map<Long, OnlineUser> getOnlineUsers() {
		return onlineUsers;
	}
	
	/**
	 * 获取Classpath物理路径
	 * @return
	 */
	public static String getClasspath(){
		 String classPath = Thread.currentThread().getContextClassLoader().getResource("").getPath();
		 String rootPath  = "";
		  //windows下
		  if("\\".equals(File.separator)){   
		   rootPath  = classPath.substring(1);
		   rootPath = rootPath.replace("/", "\\");
		  }
		  //linux下
		  if("/".equals(File.separator)){   
		   rootPath  = classPath.substring(1);
		   rootPath = rootPath.replace("\\", "/");
		  }
		  return rootPath;
	}
	
	/**
	 * Spring发布事件。
	 * @param applicationEvent
	 */
	public static void publishEvent(ApplicationEvent applicationEvent){
		applicationContext.publishEvent(applicationEvent);
	}

spring启动监听器实现代码:

public class StartupListner extends ContextLoaderListener {
	@Override
	public void contextInitialized(ServletContextEvent event) {
		super.contextInitialized(event);
		AppUtil.init(event.getServletContext());
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值