ApplicationContext特色功能详解

转载:http://youyu4.iteye.com/blog/2346183

ApplicationContext还在功能上做了扩展,相较于BeanFactorty,ApplicationContext还提供了以下的功能: 
(1)提供国际化的消息访问  (MessageSource)
(2)资源访问,如URL和文件  (ResourceLoader)
(3)载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层 
(4)消息发送、响应机制(ApplicationEventPublisher)
(5)AOP(拦截器)

(1)国际化(MessageSource)
 
1. 在xml中配置messageSource
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<!-- 资源国际化测试 -->
<bean id="messageSource"
class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
<property name="basenames">
<list>
<value>org/rjstudio/spring/properties/messages</value>
</list>
</property>
</bean>
</beans>

2. “org/rjstudio/spring/properties/messages”,是指org.rjstudio.spring.proerties包下的以messages为主要名称的properties文件
 
文件如下:
messages_en_US.properties
messages_zh_CN.properties
messages_zh_HK.properties
 
3. 取值的时候是通过ApplicationContext.getMessage(),拿到对应语言的内容
public class MessageTest {
	public static void main(String[] args) {
		ApplicationContext ctx = new ClassPathXmlApplicationContext("messages.xml");
		Object[] arg = new Object[] { "Erica", Calendar.getInstance().getTime() };
		String msg = ctx.getMessage("userinfo", arg, Locale.CHINA);
		System.out.println("Message is ===> " + msg);
	}
}


(2)资源访问(ResourceLoader)
这是spring对资源文件(如:properties)进行存取操作的功能
 ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");

1.通过虚拟路径来存取。当资源位于CLASSPATH路径下时,可以采用这种方式来存取。
Resource resource = ctx.getResource("classpath:messages_en_CN.properties");

2.通过绝对路径存取资源文件。
Resource resource = ctx.getResource("file:F:/testwork/MySpring/src/messages_en_CN.properties");

3.相对路径读取资源文件。
Resource resource = ctx.getResource("/messages_en_CN.properties");

Resource常用的方法:
getFilename() : 获得文件名称 
contentLength() : 获得文件大小 
createRelative(path): 在资源的相对地址上创建新文件 
exists(): 是否存在 
getFile(): 获得Java提供的File 对象 
getInputStream() : 获得文件的流 
 

(3)载入多个上下文
 
不同项目使用不同分模块策略,spring配置文件分为:
applicationContext.xml (主文件,包括JDBC配置,hibernate.cfg.xml,与所有的Service与DAO基类)
applicationContext-cache.xml (cache策略,包括hibernate的配置)
applicationContext-jmx.xml (JMX,调试hibernate的cache性能)
applicationContext-security.xml (acegi安全)
applicationContext-transaction.xml (事务)
moduleName-Service.xml (服务层)
moduleName-dao.xml (数据访问层)
 
两种方法配置
 
1.可以在applicationContext.xml文件中引用
<beans>
	<import resource="applicationContext-cache.xml" />
	<import resource="applicationContext-transaction.xml" />
</beans>

2.或者在web.xml文件中引用
<context-param>
	<param-name>contextConfigLocation</param-name>
	<param-value>
		WEB-INF/classes/applicationContext-security.xml
		,WEB-INF/classes/applicationContext-dao.xml
		,WEB-INF/classes/applicationContext-Service.xml
	</param-value>
</context-param>
<listener>
	<listener-class>
		org.springframework.web.context.ContextLoaderListener
	</listener-class>
</listener>


(4)spring事件机制(订阅发布模式 == 观察者模式)
 
ApplicationContext事件机制是观察者设计模式的 实现,通过ApplicationEvent类和ApplicationListener接口,可以实现ApplicationContext事件处理。 如果容器中有一个ApplicationListener Bean,每当ApplicationContext发布ApplicationEvent时,ApplicationListener Bean将自动被触发。
 
两个重要成员
ApplicationEvent:容器事件,必须由ApplicationContext发布;
ApplicationListener:监听器,可由容器中的任何监听器Bean担任。
 
1. 定义容器事件
package com.cxg.test.springPlatfrom;

import org.springframework.context.ApplicationEvent;

/**
 * Title: email之事件类 EmailEvent类继承了ApplicationEvent类,除此之外,它就是一个普通的Java类
 * Description: dataPlatfrom
 *
 * @author: xg.chen
 * @date:2016年8月24日
 */
public class EmailEvent extends ApplicationEvent {
	private static final long serialVersionUID = 1L;
	// 属性
	private String address;
	private String text;

	// 构造方法
	public EmailEvent(Object source) {
		super(source);
	}

	public EmailEvent(Object source, String address, String text) {
		super(source);
		this.address = address;
		this.text = text;
	}

	// getter和setter设置
	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public String getText() {
		return text;
	}

	public void setText(String text) {
		this.text = text;
	}
}

2. 定义监听器
package com.cxg.test.springPlatfrom;

import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;

/**
 * Title: email之监听类 容器事件的监听器类必须实现ApplicationListener接口,实现该接口就必须实现 Description:
 * dataPlatfrom
 *
 * @author: xg.chen
 * @date:2016年8月24日
 */
public class EmailNotifier implements ApplicationListener<ApplicationEvent> {

	@Override
	public void onApplicationEvent(ApplicationEvent event) {
		if (event instanceof EmailEvent) {
			EmailEvent emailEvent = (EmailEvent) event;
			System.out.println("email's address:" + emailEvent.getAddress());
			System.out.println("email's text:" + emailEvent.getText());
		} else {
			System.out.println("the Spring's event:" + event);
		}
	}

}

3. 将监听器注入到spring容器
<!-- 配置事件监听 -->
<bean class="com.cxg.test.springPlatfrom.EmailNotifier" />  

4. 测试
package com.cxg.test.springPlatfrom;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * Title: Spring的ApplicationContexet单元成测试 Description: dataPlatfrom
 *
 * @author: xg.chen
 * @date:2016年8月24日
 */
public class SpringTest {
	public static void main(String arg[]) {
		// 读取Spring容器的配置文件
		@SuppressWarnings("resource")
		ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
		// 创建一个事件对象
		EmailEvent emailEvent = new EmailEvent("hello Spring!", "cxg@126.com",
				"This is SpringApplicatoinContext test!");
		// 主动触发事件监视机制
		applicationContext.publishEvent(emailEvent);
	}
}


(5)spring的AOP(常用的是拦截器)
 
一般拦截器都是实现HandlerInterceptor,其中有三个方法preHandle、postHandle、afterCompletion
 
1. preHandle:执行controller之前执行
2. postHandle:执行完controller,return modelAndView之前执行,主要操作modelAndView的值
3. afterCompletion:controller返回后执行

实现步骤:

1. 注册拦截器,并且确定拦截器拦截哪些URL
<!-- Check Session -->
<bean id="validateSystemUserSessionInterceptor"
	class="com.cherrypicks.appsdollar.cms.interceptor.ValidateSystemUserSessionInterceptor" />

<!-- Interceptors -->
<mvc:interceptors>
	<mvc:interceptor>
		<mvc:mapping path="/**" />
		<mvc:exclude-mapping path="/login" />
		<mvc:exclude-mapping path="/logout" />
		<!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->
		<ref bean="validateSystemUserSessionInterceptor" />
	</mvc:interceptor>
</mvc:interceptors>
<!-- SpringMVC.end} -->

2. 定义拦截器实现类
package com.cherrypicks.appsdollar.cms.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import com.cherrypicks.appsdollar.common.constant.Constants;
import com.cherrypicks.appsdollar.common.exception.InvalidUserSessionException;
import com.cherrypicks.appsdollar.service.cms.CmsUserSessionService;

public class ValidateSystemUserSessionInterceptor extends HandlerInterceptorAdapter {

	private final Log logger = LogFactory.getLog(this.getClass());

	@Autowired
	private CmsUserSessionService userSessionService;

	@Override
	public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
			throws Exception {
		logger.debug("ValidateUserSessionInterceptor.preHandle run....");

		final String userIdStr = request.getParameter(Constants.USERID);
		final String sessionId = request.getParameter(Constants.SESSIONID);
		if (!StringUtils.isNotBlank(userIdStr) || !StringUtils.isNotBlank(sessionId)) {
			throw new InvalidUserSessionException(
					"Invalid user session. userId[" + userIdStr + "], sessionId[" + sessionId + "]");
		}

		final Long userId = Long.parseLong(userIdStr);

		// validate userId and sessionId
		if (!userSessionService.validateUserSession(userId, sessionId)) {
			throw new InvalidUserSessionException(
					"Invalid user session. userId[" + userId + "], sessionId[" + sessionId + "]");
		}

		return true;
	}

	public static void main(final String[] args) {
		final String i = "a";
		System.out.println(StringUtils.isNotBlank(i));
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值