Web项目中发现有人如此获得Spring的上下环境:
public class SpringUtil {
public static ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
public static Object getBean(String serviceName){
return context.getBean(serviceName);
}
}
在web项目中这种方式非常不可取!!!
分析:
首先,主要意图就是获得Spring上下文;
其次,有了Spring上下文,希望通过getBean()方法获得Spring管理的Bean的对象;
最后,为了方便调用,把上下文定义为static变量或者getBean方法定义为static方法;
但是,在web项目中,系统一旦启动,web服务器会初始化Spring的上下文的,我们可以很优雅的获得Spring的ApplicationContext对象。
如果使用
new ClassPathXmlApplicationContext(“applicationContext.xml”);
相当于重新初始化一遍!!!!
也就是说,重复做启动时候的初始化工作,第一次执行该类的时候会非常耗时!!!!!
正确的做法是:
@Component
public class SpringContextUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext; // Spring应用上下文环境
/*
* 实现了ApplicationContextAware接口,必须实现该方法;
*通过传递applicationContext参数初始化成员变量applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringContextUtil.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
@SuppressWarnings(“unchecked”)
public static T getBean(String name) throws BeansException {
return (T) applicationContext.getBean(name);
}
}
注意:这个地方使用了Spring的注解@Component,如果不是使用annotation的方式,而是使用xml的方式管理Bean,记得写入配置文件
其实
ApplicationContext context = new ClassPathXmlApplicationContext(“applicationContext.xml”);
这种方式获取Sping上下文环境,最主要是在测试环境中使用,比如写一个测试类,系统不启动的情况下手动初始化Spring上下文再获取对象!
—————————————————————–
1、思路:
应用程序启动时使用ApplicationContextAware让Spring容器传递自己生成的ApplicationContext给我们, 然后我们把这个ApplicationContext设置成一个类的静态变量, 这样我们就随时都可以在老的代码里得到Application的对象了。
2、编写工具类:ApplicationContextHelper
/**
* 版权所有:华信软件
* 项目名称:ACWS框架
* 创建者: Wangdf
* 创建日期: 2014-4-2
* 文件说明: Spring工具栏
*/
packagecom.huaxin.framework.core.util;
importorg.springframework.beans.BeansException;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.ApplicationContextAware;
/**
* Spring工具栏
* @author wangdf
*/
publicclassApplicationContextHelperimplementsApplicationContextAware {
privatestaticApplicationContext appCtx;
/**
* 此方法可以把ApplicationContext对象inject到当前类中作为一个静态成员变量。
* @param applicationContext ApplicationContext 对象.
* @throws BeansException
* @author wangdf
*/
@Override
publicvoidsetApplicationContext( ApplicationContext applicationContext )throwsBeansException {
appCtx = applicationContext;
}
/**
* 获取ApplicationContext
* @return
* @author wangdf
*/
publicstaticApplicationContext getApplicationContext(){
returnappCtx;
}
/**
* 这是一个便利的方法,帮助我们快速得到一个BEAN
* @param beanName bean的名字
* @return 返回一个bean对象
* @author wangdf
*/
publicstaticObject getBean( String beanName ) {
returnappCtx.getBean( beanName );
}
}/**
* 版权所有:华信软件
* 项目名称:ACWS框架
* 创建者: Wangdf
* 创建日期: 2014-4-2
* 文件说明: Spring工具栏
*/
package com.huaxin.framework.core.util;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
/**
* Spring工具栏
* @author wangdf
*/
public class ApplicationContextHelper implements ApplicationContextAware {
private static ApplicationContext appCtx;
/**
* 此方法可以把ApplicationContext对象inject到当前类中作为一个静态成员变量。
* @param applicationContext ApplicationContext 对象.
* @throws BeansException
* @author wangdf
*/
@Override
public void setApplicationContext( ApplicationContext applicationContext ) throws BeansException {
appCtx = applicationContext;
}
/**
* 获取ApplicationContext
* @return
* @author wangdf
*/
public static ApplicationContext getApplicationContext(){
return appCtx;
}
/**
* 这是一个便利的方法,帮助我们快速得到一个BEAN
* @param beanName bean的名字
* @return 返回一个bean对象
* @author wangdf
*/
public static Object getBean( String beanName ) {
return appCtx.getBean( beanName );
}
}
3、在Spring的配置文件中配置上述类后、应用程序启动时会使用ApplicationContextAware让Spring容器传递自己生成的ApplicationContext给我们, 然后我们把这个ApplicationContext设置成一个类的静态变量, 这样我们就随时都可以在老的代码里得到Application的对象了。
4、获得bean的方法、获取数据库连接的方法、获取ApplicationContext
4.1、取得通过Spring配置文件注入的任意Bean(以取得DataSource为例)
init-method=’init’destroy-method=”close”>
init-method=’init’destroy-method=”close”>
//取得数据源
DruidDataSource dataSource = (DruidDataSource)ApplicationContextHelper.getBean(“dataSource”);
Connection connection = DataSourceUtils.getConnection(dataSource);
//取得ApplicationContext
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();//取得数据源
DruidDataSource dataSource = (DruidDataSource)ApplicationContextHelper.getBean(“dataSource”);
Connection connection = DataSourceUtils.getConnection(dataSource);
//取得ApplicationContext
ApplicationContext ctx = ApplicationContextHelper.getApplicationContext();
4.2、取得通过注解方式注入的Bean(以在取得Service为例)
通过@Service(“userTestService”)定义bean
@Service(“userTestService”)
publicclassUserTestServiceImplimplementsUserTestService {
@Autowired
privateUserTestDao userDao;
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@Override
publicMap doGetRecordById() {
returnuserDao.getRecordById(“1”);
}
。。。略。。。
}@Service(“userTestService”)
public class UserTestServiceImpl implements UserTestService {
@Autowired
private UserTestDao userDao;
@Transactional(propagation=Propagation.NOT_SUPPORTED)
@Override
public Map doGetRecordById() {
return userDao.getRecordById(“1”);
}
。。。略。。。
}
通过以下代码获取Bean
/**
* 测试Bean获取
* @throws Exception
*/
@Test
publicvoidtestGetBean()throwsException{
//通过注解方式
UserTestService userTestService = (UserTestService)ApplicationContextHelper.getBean(“userTestService”);
System.out.println(userTestService);
}