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

 

 
 
 
     
             
             
                org/rjstudio/spring/properties/messages 
             
         
     
 

 

 

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文件中引用

    标记之间引入其他applicationContext.xml 

   

         

   

 

2.或者在web.xml文件中引用

   

     contextConfigLocation

     

         WEB-INF/classes/applicationContext-security.xml

        ,WEB-INF/classes/applicationContext-dao.xml

        ,WEB-INF/classes/applicationContext-Service.xml

     

   

   

     

            org.springframework.web.context.ContextLoaderListener

     

   

 

 

 

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{

    @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容器

 


 

 

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!", "[email protected]", "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


    
    
    
    
        
            
            
            
             
            
        
    
    

 

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--基础)