zoukankan      html  css  js  c++  java
  • spring基础学习

    ClassXmlAplicationContext和FileSystemXmlApplicationContext的区别      https://www.cnblogs.com/sxdcgaq8080/p/5650404.html

    spring学习-ApplicationContext-spring上下文深入理解

    1、SPring 容器

    基于 Spring 的应用中,所有的对象(即bean)生存于 Spring 容器,Spring 负责创建、装配、配置并管理这些bean的整个生命周期。

    一、Spring 容器

    Spring 容器并不是只有一个实现,而是自带了多个容器实现,可归纳为两种不同类型:bean 工厂、应用上下文。

    bean工厂:由 org.springframework.beans.factory.BeanFactory接口定义;

    ApplicationContext:由 org.springframework.context.ApplicationContext接口定义。

    两类别关系:ApplicationContext 基于 BeanFactory 构建,并提供应用框架级别的服务,即BeanFactory是基础,ApplicationContext是一个提升。

    二、BeanFactory

    基础接口定义:

    public interface BeanFactory {
        String FACTORY_BEAN_PREFIX = "&";
        Object getBean(String name) throws BeansException;
        <T> T getBean(String name, Class<T> requiredType) throws BeansException;
        <T> T getBean(Class<T> requiredType) throws BeansException;
        Object getBean(String name, Object... args) throws BeansException;
        boolean containsBean(String name);
        boolean isSingleton(String name) throws NoSuchBeanDefinitionException;
        boolean isPrototype(String name) throws NoSuchBeanDefinitionException;
        boolean isTypeMatch(String name, Class<?> targetType) throws NoSuchBeanDefinitionException;
        Class<?> getType(String name) throws NoSuchBeanDefinitionException;
        String[] getAliases(String name);
    }

    三、ApplicationContext

    基础继承关系:

    public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
            MessageSource, ApplicationEventPublisher, ResourcePatternResolver{...}
    可见ApplicationContext是在BeanFactory基础上定义的,实际上ApplicationContext是BeanFactory的一个超全集。

    /**
    * ApplicationContext是一个为application提供配置信息的中心接口,当application运行时,它仅是可读的,但也可能重新加载,如果接口允许的 * 话。
    * ApplicationContex提供了如下功能:
    *
    * 1、访问application的组件(即bean)的BeanFactory中的方法。继承于:org.springframework.beans.factory.ListableBeanFactory;
    * 2、以常规方式加载文件资源的能力。继承于:org.springframework.core.io.ResourceLoader;
    * 3、发布Event到注册过的listener的能力。继承于:ApplicationEventPublisher;
    * 4、解决message的能力,即支持国际化。继承于:MessageSource;
    * 从父上下文继承,在后代语境中的定义将永远优先。 这意味着,例如,一个单亲上下文可以由整个Web应用程序使用,而每个servlet都有它独立于任何其他servlet的子环境。(不明白)
    * 除了标准的org.springframework.beans.factory.BeanFactory的生命周期的能力外,ApplicationContext实现检测和调用
    * ApplicationContextAware bean 、ResourceLoaderAware bean
    * 及ApplicationEventPublisherAware、MessageSourceAware bean。
    */

    通过集成实现的接口就知道他具有spring里面经典的工厂方法,还有对国际化支持的Message,以及配置信息的Resource,还有spring支持的发布和监听事件功能。一个Context基本上把spring具有的核心功能都包裹起来了,那么这就是spring框架运行需要的环境,也就是常说的上下文。任何一个框架运行都通过一个类来进行描述它执行时的环境,ServletContext也是一样,就是Servlet环境信息。可以将context理解为一个框架执行信息的载体,可以理解问一个框架的门面(门面模式),将框架内部的各个组件信息都通过一个context暴露给外部。

    所以Application 比BeanFactory多了3项能力:加载资源文件能力、发布事件能力、国际化能力。看第四点中示例!

    关于Aware 接口的基础,查看另外一篇日志:


    四、ApplicationContext增强能力

    第三点列了ApplicationContext 增加的3项能力,现分别举基础例子。

    1、资源加载:ResourceLoader接口

    ResourceLoader接口定义:

    public interface ResourceLoader {
     
        /** 从class path 路径加载时的伪资源URL: "classpath:" 。不陌生,web.xml配置中指定类路径下资源时便要加此前缀*/
        String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
     
        /**返回指定path的资源*/
        Resource getResource(String location);
     
        /**需要直接访问ClassLoader的客户端可以这样做,即以与ResourceLoader统一的方式,而不是依赖线程上下文ClassLoader*/
        ClassLoader getClassLoader();
    }

    说明:

    Resource 也是一个接口,定义如下:

    public interface Resource extends InputStreamSource {
    
    /**说明:InputStreamSource接口中只有一个方法:InputStream getInputStream()。可见Resource本质上是一个输入流,只是丰富了方法。*/
        boolean exists();
        boolean isReadable();
        boolean isOpen();
        URL getURL() throws IOException;
        URI getURI() throws IOException;
        File getFile() throws IOException;        //常用方法
        long contentLength() throws IOException;
        long lastModified() throws IOException;
        Resource createRelative(String relativePath) throws IOException;
        String getFilename();
        String getDescription();
    }

    问题:
    已经可以通过ResourceLoader 返回Resource 对象得到我们需要的文件了,那ResourceLoader 中getClassLoader方法有什么作用?

    答:ClassLoader是java.lang包中的类,用于JVM 加载class文件,这些class文件也是广义上的资源。在ResourceLoader 中定义方法得到此类的目的应该是application运行时并不是一下子把应用所涉及的class文件都加载,而是先加载核心的,再加载我们自己写的代码生成的类,且是用到时再加载。ClassLoader 保存了加载某个class文件时所用的位置(可能是本地,也可能是网络服务器上),所以在一个已加载的A.class文件中涉及到另一个B.class的对象时,便可以通过getClassLoader 从加载A.class的资源路径中加载B.class,之后生成对象,因为A.class与B.class在web系统中都是是位于服务器上的。简言之,两个class对应了两个java文件,A.java中使用了B.java中的类,则程序执行到A.class时,A.class从哪加载的,B.class也从那加载(或许还会自动扫描那台主机上ClassPath的所有目录,以找到B.class)。

    <p> Normally, the Java virtual machine loads classes from the local file
     * system in a platform-dependent manner.  For example, on UNIX systems, the
     * virtual machine loads classes from the directory defined by the
     * <tt>CLASSPATH</tt> environment variable.
     *
     * <p> However, some classes may not originate from a file; they may originate
     * from other sources, such as the network, or they could be constructed by an
     * application.  The method {@link #defineClass(String, byte[], int, int)
     * <tt>defineClass</tt>} converts an array of bytes into an instance of class
     * <tt>Class</tt>. Instances of this newly defined class can be created using
     * {@link Class#newInstance <tt>Class.newInstance</tt>}.

    ResourceLoader示例:

    ApplicationContext继承了ResourceLoader接口,所以可以直接获取文件。

    ApplicationContext appCtx=FileSystemXMLApplication("applicationContext.xml");
    Resource reSrc=appCtx.getResource("sourceURL");
    //使用Resource对象获取文件
    File file=reSrc.getFile();
    注:sourceURL可以是"classpath:"开头的类路径,也可是"WEB-INF/src/"开头的路径,更可以是绝对路径。

    2、事件发布:ApplicationEvent类、ApplicationListener接口、ApplicationContextAware接口

    步骤:

    (1)、写一个事件类,继承ApplicationEvent 类。如:

    class SayHello enxtends ApplicationEvent{
        public SayHello(){super();}
    }

    (2)、写一个ApplicationEvent 事件监听类,实现 ApplicationListener接口。如:

    class SayListener implement ApplicationListener{
        public void onApplicationEvent(ApplicationEvent ev){
            if(ev instanceof SayHello){
                System.out.println("收到SayHello事件");
            }
        }
    }

    (3)、写一个事件发布管理类,实现ApplicationContextAware 接口。如:

    public class ManagerEvent implements ApplicationContextAware{
        private ApplicationContext appCtx=null;
        @Override
        public void setApplicationContext(ApplicationContext applicationContext)
                throws BeansException {
            appCtx=applicationContext;
        }
        public void publish(ApplicationEvent event){/*此处运用了控制翻转的思想,即传入ApplicationEvent的子类,因为是类的继承而非接口的实现,所以在SayHello类中并没有添加实际的方法,只是用于区分事件而已*/
            if(event!=null)
                appCtx.publisherEvent(event);
        }
    }

    (3)、配置Spring 容器中的bean,可通过XML 配置,如:WEB-INF/src下的myConfig.xml:省略了xml声明部门

    <beans>
        <bean id="hellowEvent" class="myPackageName.SayHello"/>
        <bean id="manageEvent" class="myPackage.ManageEvent"/>
        <bean id="listerner" class="myPackage.SayListener"/>
    </beans>

    (4)、测试:主函数部分代码:

    public static void main(String[] args){
        ApplicationContext appCtx=new FileSystemApplicationContext("WEB-INF/src/myConfig.xml");
        SayHello event=appCtx.getBean("hellowEvent");
        ManageEvent manage=appCtx.getBean("manageEvent");
        manage.publish(event);//发布事件
    }

    说明:

    Spring 所有bean位于一个容器中,即ApplicationContext或BeanFactory中,所以所有的操作都是依赖于这个容器,容器定义后,不能重新定义,只能通过refresh方法(有待补充)。如果某个bean中本身要使用容器的某个功能,应该实现ApplicationContextAware 接口,获得ApplicationContext的句柄,对其它***Aware方法同理。

    3、国际化:MessageResource接口

    见另一边日志:http://blog.csdn.net/qq_19865749/article/details/70195063

    五、几个常用ApplicationContext

    使用Spring 的基础是通过XML等形式定义一些JavaBean,之后使用Spring 的BeanFactory 或ApplicationContext 创建并管理这些JavaBean,常用的几个ApplicationContext :

    1、FileSystemXmlApplicationContext:

    从文件系统下的一个或多个XML 配置文件加载上下文定义。

    示例:

    ApplicationContext appCtx=new FileSystemXmlApplicationContext(new String[]{"WebContent/WEB-INF/applicationContext.xml","WebContent/WEB-INF/config.xml"});//以String数组形式传入多个xml文件路径

    说明:

    查找路径默认为工程文件夹下,所以若XML文件不是直接处于工程文件夹下,则应把路径写上,如上面的 WebContent/WEB-INF/。也可用绝对路径。

    2、ClassPathXMLApplicationContext:

    从类路径下的一个或多个XML 配置文件加载上下文定义。

    示例:

    ApplicationContext appCtx=new ClassPathXmlApplicationContext("applicationContext.xml");
    说明:
    查找路径默认为src下,所以同上,若XML 文件不是直接属于src文件夹下,则应该加上路径,如:xml文件放在com.milan.pojo包下,则应为:
    ApplicationContext appCtx=new ClassPathXmlApplicationContext("com/milan/pojo/applicationContext.xml");

    3、XmlWebApplicationContext:

    从Web 应用下的一个或多个XML 配置文件中加载上下文定义。

     

     

  • 相关阅读:
    x64 平台开发 Mapxtreme 编译错误
    hdu 4305 Lightning
    Ural 1627 Join(生成树计数)
    poj 2104 Kth Number(可持久化线段树)
    ural 1651 Shortest Subchain
    hdu 4351 Digital root
    hdu 3221 Bruteforce Algorithm
    poj 2892 Tunnel Warfare (Splay Tree instead of Segment Tree)
    hdu 4031 Attack(BIT)
    LightOJ 1277 Looking for a Subsequence
  • 原文地址:https://www.cnblogs.com/wwmiert/p/11447887.html
Copyright © 2011-2022 走看看