BeanFactory和ApplicationContext的区别
描述
BeanFactory:
是Spring里面最低层的接口,提供了最简单的容器的功能,只提供了实例化对象和拿对象的功能;
ApplicationContext:
应用上下文,继承BeanFactory接口,它是Spring的一各更高级的容器,提供了更多的有用的功能;
1) 国际化(MessageSource)
2) 访问资源,如URL和文件(ResourceLoader)
3) 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层
4) 消息发送、响应机制(ApplicationEventPublisher)
5) AOP(拦截器)
两者装载bean的区别
BeanFactory:
BeanFactory在启动的时候不会去实例化Bean,中有从容器中拿Bean的时候才会去实例化;
ApplicationContext:
ApplicationContext在启动的时候就把所有的Bean全部实例化了。它还可以为Bean配置lazy-init=true来让Bean延迟实例化;
我们该用BeanFactory还是ApplicationContent
延迟实例化的优点:(BeanFactory)
应用启动的时候占用资源很少;对资源要求较高的应用,比较有优势;
不延迟实例化的优点: (ApplicationContext)
1. 所有的Bean在启动的时候都加载,系统运行的速度快;
2. 在启动的时候所有的Bean都加载了,我们就能在系统启动的时候,尽早的发现系统中的配置问题
3. 建议web应用,在启动的时候就把所有的Bean都加载了。(把费时的操作放到系统启动中完成)
spring国际化例子(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); } }
spring访问资源(ResourceLoader)
这是spring对资源文件(如:properties)进行存取操作的功能
ApplicationContext acxt =new ClassPathXmlApplicationContext("/applicationContext.xml");
1.通过虚拟路径来存取。当资源位于CLASSPATH路径下时,可以采用这种方式来存取。
Resource resource = acxt.getResource("classpath:messages_en_CN.properties");
2.通过绝对路径存取资源文件。
Resource resource = acxt.getResource("file:F:/testwork/MySpring/src/messages_en_CN.properties");
3.相对路径读取资源文件。
Resource resource = acxt.getResource("/messages_en_CN.properties");
Resource常用的方法:
getFilename() : 获得文件名称
contentLength() : 获得文件大小
createRelative(path) : 在资源的相对地址上创建新文件
exists() : 是否存在
getFile() : 获得Java提供的File 对象
getInputStream() : 获得文件的流
spring载入多个上下文
不同项目使用不同分模块策略,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></beans>标记之间引入其他applicationContext.xml
<beans>
<import resource="applicationContext-cache.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>
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); } }
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)); } }
参考
http://kouhao123.iteye.com/blog/1633574
http://m.blog.csdn.net/article/details?id=51112702
http://blog.csdn.net/EthanWhite/article/details/52445346
http://site.leshou.com/s/12730359.html
http://elim.iteye.com/blog/1750680
相关推荐
在Spring框架中,BeanFactory和ApplicationContext是两种不同的bean容器,它们各自有其特性和应用场景,理解二者的区别对于深入掌握Spring框架至关重要。 首先,BeanFactory是Spring中最基本的bean容器,它提供了对...
在Spring框架中,ApplicationContext和BeanFactory是两种不同的bean容器,它们各自有其特性和应用场景,理解二者的区别对于深入学习和使用Spring至关重要。 首先,BeanFactory是Spring中最基础的bean管理容器,它...
在Java的Spring框架中,`BeanFactory`和`ApplicationContext`是两个非常重要的核心概念,它们是IoC(Inversion of Control,控制反转)容器的实现,用于管理应用程序中的对象和依赖关系。理解这两个容器的区别和用途...
Spring的IoC容器是其核心特性之一,它通过BeanFactory和ApplicationContext两个主要接口来实现控制反转(Inversion of Control,IoC)的概念。BeanFactory作为基础的IoC容器,提供了全面的IoC服务,包括对象的注册、...
BeanFactory 和 ApplicationContext 有什么区别 > BeanFactory 可以理解为含有 bean 集合的工厂类。BeanFactory 包含了种 bean 的定 义, 以便在接收到客户端请求时将对应的 bean 实例化。 > BeanFactory 还能在实例...
BeanFactory和FactoryBean的主要区别在于: * BeanFactory是Spring IoC容器的核心接口,而FactoryBean是一个特殊的Bean。 * BeanFactory提供了Bean的实例化、管理和依赖注入等功能,而FactoryBean可以生成其他Bean...
3. **BeanFactory与ApplicationContext的区别** BeanFactory是Spring中最基本的容器,它负责创建、管理和查找bean。ApplicationContext则在BeanFactory的基础上增加了很多企业级服务,如国际化、事件广播、应用上...
在Spring框架中,BeanFactory是核心的容器,它负责管理和创建对象,这些对象通常被称为"bean"。...在实际开发中,通常会结合使用BeanFactory和ApplicationContext,以充分利用Spring提供的各种特性。
在 Spring 框架中,BeanFactory 是一个核心组件,负责管理和实例化 Bean。Spring 3 中提供了三种实例化 BeanFactory 的方法,下面将详细介绍这三种方法。 第一种方法:从文件系统资源实例化 BeanFactory 在 Spring...
三、BeanFactory与ApplicationContext的区别 虽然BeanFactory是基础,但实际开发中更多使用的是其子类ApplicationContext。ApplicationContext除了具备BeanFactory的所有功能外,还添加了以下特性: 1. **资源加载**...
这份文档是对Java面试知识的自我总结,涵盖了Spring框架的核心概念,特别是AOP(面向切面编程)和Spring的启动过程,以及BeanFactory和ApplicationContext的区别,以及Spring Bean的生命周期。 1. **Spring的AOP...
在Spring应用中,通常会使用ApplicationContext来替代简单的BeanFactory,因为ApplicationContext提供了一站式的解决方案,能够更好地管理和协调复杂的系统组件。 当我们创建ApplicationContext时,可以通过XML配置...
在Spring框架中,BeanFactory和ApplicationContext是两种不同的bean容器,它们在管理bean上有共同之处,但也存在明显的区别。BeanFactory可以视为一个基本的bean仓库,它包含bean的定义并在需要时实例化bean,同时...
在Spring中,ApplicationContext(应用程序上下文)是容器的核心,负责配置和管理应用中对象的生命周期和依赖关系。在实际开发过程中,经常需要从各个角落获取到这个ApplicationContext对象,以便于能够使用Spring...
Spring框架的核心在于其IoC容器,通过BeanFactory和ApplicationContext接口提供了强大的依赖注入功能。开发者可以根据项目的需要选择合适的容器类型和配置方式,以实现高效、可维护的代码结构。随着Spring框架的发展...
BeanFactory 和 ApplicationContext 有什么区别 > BeanFactory 可以理解为含有 bean 集合的工厂类。BeanFactory 包含了种 bean 的定义, 以便在接收到客户端请求时将对应的 bean 实例化。 > BeanFactory 还能在实例...
在Spring框架中,`ApplicationContext`是`BeanFactory`接口的一个扩展,提供了更为丰富的功能和服务。它不仅继承了`BeanFactory`的所有特性,还增加了如资源加载、消息源国际化、事件发布等高级特性。这使得`...
通过BeanFactory和ApplicationContext,开发者可以更专注于业务逻辑,而不是对象的创建和管理。依赖注入的方式多样,满足不同场景的需求,而WebApplicationContext则为Web应用提供了无缝的整合和支持。理解和掌握...
Resource接口提供了一种统一的方式来访问各种类型的资源,而BeanFactory和ApplicationContext则构成了Spring的核心IoC容器,管理着应用中的Bean和它们的生命周期。这些概念对于任何想要深入学习和使用Spring框架的...