BeanFactory和ApplicationContext的区别

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代码 

 收藏代码

  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">   
  3. <beans>   
  4.     <!-- 资源国际化测试 -->   
  5.     <bean id="messageSource"        class="org.springframework.context.support.ReloadableResourceBundleMessageSource">        <property name="basenames">   
  6.             <list>   
  7.                 <value>org/rjstudio/spring/properties/messages</value>   
  8.             </list>   
  9.         </property>   
  10.     </bean>   
  11. </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(),拿到对应语言的内容

Java代码 

 收藏代码

  1. public class MessageTest {   
  2.     public static void main(String[] args) {   
  3.         ApplicationContext ctx = new ClassPathXmlApplicationContext("messages.xml");   
  4.         Object[] arg = new Object[] { "Erica", Calendar.getInstance().getTime() };   
  5.         String msg = ctx.getMessage("userinfo", arg,Locale.CHINA);   
  6.         System.out.println("Message is ===> " + msg);   
  7.     }   
  8. }   

 

 

 

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. 定义容器事件

 

Java代码 

 收藏代码

  1. package com.cxg.test.springPlatfrom;  
  2.   
  3. import org.springframework.context.ApplicationEvent;  
  4. /** 
  5.  * Title: email之事件类 
  6.  * EmailEvent类继承了ApplicationEvent类,除此之外,它就是一个普通的Java类 
  7.  * Description: dataPlatfrom 
  8.  * @author: xg.chen 
  9.  * @date:2016年8月24日 
  10.  */  
  11. public class EmailEvent extends ApplicationEvent{  
  12.     private static final long serialVersionUID = 1L;  
  13.     //属性  
  14.     private String address;  
  15.     private String text;  
  16.     //构造方法  
  17.     public EmailEvent(Object source) {  
  18.         super(source);  
  19.     }  
  20.     public EmailEvent(Object source, String address, String text) {  
  21.         super(source);  
  22.         this.address = address;  
  23.         this.text = text;  
  24.     }  
  25.     //getter和setter设置  
  26.     public String getAddress() {  
  27.         return address;  
  28.     }  
  29.     public void setAddress(String address) {  
  30.         this.address = address;  
  31.     }  
  32.     public String getText() {  
  33.         return text;  
  34.     }  
  35.     public void setText(String text) {  
  36.         this.text = text;  
  37.     }  
  38. }  

 

 

2. 定义监听器

 

Java代码 

 收藏代码

  1. package com.cxg.test.springPlatfrom;  
  2.   
  3. import org.springframework.context.ApplicationEvent;  
  4. import org.springframework.context.ApplicationListener;  
  5. /** 
  6.  * Title: email之监听类 
  7.  * 容器事件的监听器类必须实现ApplicationListener接口,实现该接口就必须实现 
  8.  * Description: dataPlatfrom 
  9.  * @author: xg.chen 
  10.  * @date:2016年8月24日 
  11.  */  
  12. public class EmailNotifier implements ApplicationListener<ApplicationEvent>{  
  13.   
  14.     @Override  
  15.     public void onApplicationEvent(ApplicationEvent event) {  
  16.         if(event instanceof EmailEvent){  
  17.             EmailEvent emailEvent = (EmailEvent) event;  
  18.             System.out.println("email's address:"+emailEvent.getAddress());  
  19.             System.out.println("email's text:"+emailEvent.getText());  
  20.         } else {  
  21.             System.out.println("the Spring's event:"+event);  
  22.         }  
  23.     }  
  24.   
  25. }  

 

 

3. 将监听器注入到spring容器

 

Xml代码 

 收藏代码

  1. <!-- 配置事件监听 -->  
  2. <bean class="com.cxg.test.springPlatfrom.EmailNotifier" />  

 

 

4. 测试

 

Java代码 

 收藏代码

  1. package com.cxg.test.springPlatfrom;  
  2.   
  3. import org.springframework.context.ApplicationContext;  
  4. import org.springframework.context.support.ClassPathXmlApplicationContext;  
  5. /** 
  6.  * Title: Spring的ApplicationContexet单元成测试 
  7.  * Description: dataPlatfrom 
  8.  * @author: xg.chen 
  9.  * @date:2016年8月24日 
  10.  */  
  11. public class SpringTest {  
  12.     public static void main(String arg[]){  
  13.         //读取Spring容器的配置文件  
  14.         @SuppressWarnings("resource")  
  15.         ApplicationContext applicationContext=new ClassPathXmlApplicationContext("application.xml");  
  16.         //创建一个事件对象  
  17.         EmailEvent emailEvent = new EmailEvent("hello Spring!", "cxg@126.com", "This is SpringApplicatoinContext test!");  
  18.         //主动触发事件监视机制  
  19.         applicationContext.publishEvent(emailEvent);  
  20.     }  
  21. }  

 

 

 

 

spring的AOP(常用的是拦截器)

 

一般拦截器都是实现HandlerInterceptor,其中有三个方法preHandle、postHandle、afterCompletion

 

1. preHandle:执行controller之前执行

2. postHandle:执行完controller,return modelAndView之前执行,主要操作modelAndView的值

3. afterCompletion:controller返回后执行

 

 

实现步骤:

 

1. 注册拦截器,并且确定拦截器拦截哪些URL

Xml代码 

 收藏代码

  1. <!-- Check Session -->  
  2.     <bean id="validateSystemUserSessionInterceptor" class="com.cherrypicks.appsdollar.cms.interceptor.ValidateSystemUserSessionInterceptor" />  
  3.       
  4.     <!-- Interceptors -->  
  5.     <mvc:interceptors>  
  6.         <mvc:interceptor>  
  7.             <mvc:mapping path="/**" />  
  8.             <mvc:exclude-mapping path="/login" />  
  9.             <mvc:exclude-mapping path="/logout" />  
  10.             <!-- 定义在mvc:interceptor下面的表示是对特定的请求才进行拦截的 -->   
  11.             <ref bean="validateSystemUserSessionInterceptor"  />  
  12.         </mvc:interceptor>  
  13.     </mvc:interceptors>  
  14.     <!-- SpringMVC.end} -->  

 

2. 定义拦截器实现类

Java代码 

 收藏代码

  1. package com.cherrypicks.appsdollar.cms.interceptor;    
  2. import javax.servlet.http.HttpServletRequest;  
  3. import javax.servlet.http.HttpServletResponse;  
  4.   
  5. import org.apache.commons.lang.StringUtils;  
  6. import org.apache.commons.logging.Log;  
  7. import org.apache.commons.logging.LogFactory;  
  8. import org.springframework.beans.factory.annotation.Autowired;  
  9. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;  
  10.   
  11. import com.cherrypicks.appsdollar.common.constant.Constants;  
  12. import com.cherrypicks.appsdollar.common.exception.InvalidUserSessionException;  
  13. import com.cherrypicks.appsdollar.service.cms.CmsUserSessionService;  
  14.   
  15. public class ValidateSystemUserSessionInterceptor extends HandlerInterceptorAdapter {  
  16.   
  17.     private final Log logger = LogFactory.getLog(this.getClass());  
  18.   
  19.     @Autowired  
  20.     private CmsUserSessionService userSessionService;  
  21.   
  22.     @Override  
  23.     public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)  
  24.             throws Exception {  
  25.         logger.debug("ValidateUserSessionInterceptor.preHandle run....");  
  26.   
  27.         final String userIdStr = request.getParameter(Constants.USERID);  
  28.         final String sessionId = request.getParameter(Constants.SESSIONID);  
  29.         if (!StringUtils.isNotBlank(userIdStr) || !StringUtils.isNotBlank(sessionId)) {  
  30.             throw new InvalidUserSessionException(  
  31.                     "Invalid user session. userId[" + userIdStr + "], sessionId[" + sessionId + "]");  
  32.         }  
  33.   
  34.         final Long userId = Long.parseLong(userIdStr);  
  35.   
  36.         // validate userId and sessionId  
  37.         if (!userSessionService.validateUserSession(userId, sessionId)) {  
  38.             throw new InvalidUserSessionException(  
  39.                     "Invalid user session. userId[" + userId + "], sessionId[" + sessionId + "]");  
  40.         }  
  41.   
  42.         return true;  
  43.     }  
  44.   
  45.     public static void main(final String[] args) {  
  46.         final String i = "a";  
  47.         System.out.println(StringUtils.isNotBlank(i));  
  48.     }  
posted @ 2022-04-01 15:01  甜菜波波  阅读(377)  评论(0编辑  收藏  举报