在使用spring的时候,我们使用Properties配置器把properties文件装载到Spring的上下文中,如下:
<!-- Loads a Properties instance -->
<util:properties id="evn" location="classpath:config/jndi.properties"></util:properties>
<context:property-placeholder location="classpath:config/ejb.properties" />
这样在Spring的配置文件中可以用表达式来获得load进来的properties内容,如下:
<jee:jndi-lookup jndi-name="${ejb-name}" id="login-loginBean"
lookup-on-startup="true" cache="true" proxy-interface="${ejb-interface}"
environment-ref="evn">
</jee:jndi-lookup>
既然spring已经能把properties读到它的上下文,在配置文件中轻松地使用,那么是不是也可以想办法让我们在代码中也能取到这些值?
那我们何不利用这一点,让我们能从代码中也使用这些值。
整理一下思路:
1、准备好配置文件,将properties的值设置到Bean中
2、初始化Spring上下文,加载properties文件
3、可以通过相应的bean去访问需要的properties的值
第1点很简单,不多说
第2点初始化Spring上下文,有很多方式,大家可以根据自己的方式选择其一即可。
方式1:
FileSystemXmlApplicationContext——从指定的目录中加载
ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml");
方式2:
ClassPathXmlApplicationContext——从classpath路径加载:
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
方式3:
ServletContext servletContext = servlet.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
方式4:
在spring和各种MVC整合的框架下,在我们自己写的代码中要使用ApplicationContext是不方便的。
spring有一个类 org.springframework.web.context.support.WebApplicationContextUtils
spring有一个类 org.springframework.web.context.support.WebApplicationContextUtils
它有一个static的方法getWebApplicationContext(ServletContext sc)
可以使我们得到一个ApplicationContext的引用, 但这个方法有一个参数ServletContext,它是Servlet容器提供的上下文,在非Servlet环境下是得不到的。 我们可以定义一个servlet,该servlet配置为被容器第一个加载,它可以得到ServletContext,从而得到ApplicationContext的引用, 我们再把这个引用保存在一个所用应用都能访问到的地方。
- package xxx.utils;
- import org.springframework.context.ApplicationContext;
- public class SpringBeanProxy {
- private static ApplicationContext applicationContext;
- public synchronized static void setApplicationContext(ApplicationContext arg0) {
- applicationContext = arg0;
- }
- public static Object getBean(String beanName){
- return applicationContext.getBean(beanName);
- }
- }
在web.xml中
- package xxx.servlets;
- import javax.servlet.ServletConfig;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import org.springframework.web.context.support.WebApplicationContextUtils;
- import xxx.utils.SpringBeanProxy;
- public class SpringBeanInitServlet extends HttpServlet {
- public void init(ServletConfig arg0) throws ServletException {
- SpringBeanProxy.setApplicationContext(WebApplicationContextUtils.getWebApplicationContext(arg0.getServletContext()));
- }
- }
由于listener先于servlet加载,所以可以确保SpringBeanInitServlet加载时spring已经初始化好了, 如果你使用的是servlet加载spring就要注意调整这两个servlet的启动顺序了。 这时可以在程序的任何地方,使用 SpringBeanProxy.getBean("beanName")得到一个bean了。
- <listener>
- <listener-class>
- org.springframework.web.context.ContextLoaderListener
- </listener-class>
- </listener>
- <servlet>
- <servlet-name>SpringBeanInitServlet</servlet-name>
- <servlet-class>
- xxx.SpringBeanInitServlet
- </servlet-class>
- <load-on-startup>1</load-on-startup>
- </servlet>
第3步,查资料知道Spring使用
org.springframework.beans.factory.config.PropertyPlaceholderConfigurer 读取properties文件。
我们可以扩展这个类来满足我们的需求。 怎么办?继承!
- /**
- * @author : jl
- * @group : tgb8
- * @Date : 2014-4-4 下午4:38:19
- * @Comments : 方便开发人员使用可以使用PropertyConfigurer.getContextProperty()来取得上下文中的properties的值了。
- * @Version : 1.0.0
- */
- public class PropertyConfigure extends PropertyPlaceholderConfigurer {
- private static Map<String, Object> ctxPropertiesMap;
- @Override
- protected void processProperties(ConfigurableListableBeanFactory beanFactory,
- Properties props) throws BeansException {
- super.processProperties(beanFactory, props);
- ctxPropertiesMap = new HashMap<String, Object>();
- for (Object key : props.keySet()) {
- String keyStr = key.toString();
- String value = props.getProperty(keyStr);
- ctxPropertiesMap.put(keyStr, value);
- }
- }
- public static Object getContextProperty(String name) {
- //初始化全局配置
- initApplicationContext("context-properties.xml");
- return ctxPropertiesMap.get(name);
- }
- private static void initApplicationContext(String key) {
- CacheHandler cacheHandler = CacheHandler.getInstance();
- Cache cache = cacheHandler.getCacheByName("ApplicationContext");
- //如果没有初始化ApplicationContext,则初始化,并放入缓存,防止下次再初始化
- if (cache == null) {
- System.out.println("创建ApplicationContext缓存");
- cache = cacheHandler.addCache("ApplicationContext");
- System.out.println("初始化ApplicationContext,key="+key);
- ApplicationContext context = new ClassPathXmlApplicationContext(
- key);
- Element elementVal = new Element(key, context);
- cache.put(elementVal);
- }
- }
- }
那么我们如何在Spring中配置呢?
<bean id="configBean" class="common.tool.config.PropertyConfigure">
<!-- <property name="location" value="classpath:url.properties" /> -->
<property name="locations">
<list>
<value>url.properties</value>
<value>wsdl.properties</value>
</list>
</property>
</bean>