• 那是从何处传来的钟声呢?偶尔听到那钟声,平添一份喜悦与向往之情。

BeanFactory和ApplicationContext的区别

后端 Nanait 5年前 (2019-09-29) 1230次浏览 已收录 0个评论 扫描二维码
  1. BeanFactoryApplicationContext的区别

     

    描述

     

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

    BeanFactory 和 ApplicationContext 的区别

    1. <?xml version=”1.0″ encoding=”UTF-8″?>
    2. <!DOCTYPE beans PUBLIC “-//SPRING//DTD BEAN//EN” “http://www.springframework.org/dtd/spring-beans.dtd”&gt;
    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 代码

    BeanFactory 和 ApplicationContext 的区别

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

    BeanFactory 和 ApplicationContext 的区别

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

     

     

    2. 定义监听器

     

    Java 代码

    BeanFactory 和 ApplicationContext 的区别

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

     

     

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

     

    Xml 代码

    BeanFactory 和 ApplicationContext 的区别

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

     

     

    4. 测试

     

    Java 代码

    BeanFactory 和 ApplicationContext 的区别

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

     

     

     

     

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

     

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

     

    1. preHandle:执行 controller 之前执行

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

    3. afterCompletion:controller 返回后执行

     

     

    实现步骤:

     

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

    Xml 代码

    BeanFactory 和 ApplicationContext 的区别

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

     

    2. 定义拦截器实现类

    Java 代码

    BeanFactory 和 ApplicationContext 的区别

    1. package com.cherrypicks.appsdollar.cms.interceptor;
    2. import javax.servlet.http.HttpServletRequest;
    3. import javax.servlet.http.HttpServletResponse;
    4. import org.apache.commons.lang.StringUtils;
    5. import org.apache.commons.logging.Log;
    6. import org.apache.commons.logging.LogFactory;
    7. import org.springframework.beans.factory.annotation.Autowired;
    8. import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    9. import com.cherrypicks.appsdollar.common.constant.Constants;
    10. import com.cherrypicks.appsdollar.common.exception.InvalidUserSessionException;
    11. import com.cherrypicks.appsdollar.service.cms.CmsUserSessionService;
    12. public class ValidateSystemUserSessionInterceptor extends HandlerInterceptorAdapter {
    13.     private final Log logger = LogFactory.getLog(this.getClass());
    14.     @Autowired
    15.     private CmsUserSessionService userSessionService;
    16.     @Override
    17.     public boolean preHandle(final HttpServletRequest request, final HttpServletResponse response, final Object handler)
    18.             throws Exception {
    19.         logger.debug(“ValidateUserSessionInterceptor.preHandle run….”);
    20.         final String userIdStr = request.getParameter(Constants.USERID);
    21.         final String sessionId = request.getParameter(Constants.SESSIONID);
    22.         if (!StringUtils.isNotBlank(userIdStr) || !StringUtils.isNotBlank(sessionId)) {
    23.             throw new InvalidUserSessionException(
    24.                     “Invalid user session. userId[” + userIdStr + “], sessionId[” + sessionId + “]”);
    25.         }
    26.         final Long userId = Long.parseLong(userIdStr);
    27.         // validate userId and sessionId
    28.         if (!userSessionService.validateUserSession(userId, sessionId)) {
    29.             throw new InvalidUserSessionException(
    30.                     “Invalid user session. userId[” + userId + “], sessionId[” + sessionId + “]”);
    31.         }
    32.         return true;
    33.     }
    34.     public static void main(final String[] args) {
    35.         final String i = “a”;
    36.         System.out.println(StringUtils.isNotBlank(i));
    37.     }
    • }

何处钟 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:BeanFactory 和 ApplicationContext 的区别
喜欢 (0)
[15211539367@163.com]
分享 (0)

您必须 登录 才能发表评论!