zoukankan      html  css  js  c++  java
  • Spring—spring概述

    Spring框架的特点?
    1:轻量级,一站式开发
    2:易用,追求代码的最佳实现
    3:Spring的内容:
    a:Ioc容器
    b:AOP实现
    c:数据访问支持(ORM框架/声明事务[Transactions模块])
    d:Web集成
     
    Spring框架的优点?
    1:低侵入式设计(有利于重用公共代码)
    2:独立应用于各种应用服务器
    3:依赖注入,将组件的关系透明化,降低耦合度
    4:面向切面编程,允许通过任务进行集中处理
    5:与第三方框架的良好整合
     
    spring 的优点?
    1.降低了组件之间的耦合性 ,实现了软件各层之间的解耦 
    2.可以使用容易提供的众多服务,如事务管理,消息服务等 
    3.容器提供单例模式支持 
    4.容器提供了AOP技术,利用它很容易实现如权限拦截,运行期监控等功能 
    5.容器提供了众多的辅助类,能加快应用的开发 
    6.spring对于主流的应用框架提供了集成支持,如hibernate,JPA,Struts等 
    7.spring属于低侵入式设计,代码的污染极低 
    8.独立于各种应用服务器 
    9.spring的DI机制降低了业务对象替换的复杂性 
    10.Spring的高度开放性,并不强制应用完全依赖于Spring,开发者可以自由选择spring的部分或全部 
     
     
    Spring核心结构体系
     
     
    核心容器(Core container)介绍
    核心:模块提供了框架的基本组成部分,包括 IoC 和依赖注入功能。
    Bean :模块提供 BeanFactory,它是一个工厂模式的复杂实现。
    上下文:模块建立在由核心和 Bean 模块提供的坚实基础上,它是访问定义和配置的任
    何对象的媒介。ApplicationContext 接口是上下文模块的重点。
    表达式语言:模块在运行时提供了查询和操作一个对象图的强大的表达式语言。
     
    数据访问/集成
    数据访问/集成层包括 JDBC,ORM,OXM,JMS 和事务处理模块,它们的细节如下:
    JDBC 模块提供了删除冗余的 JDBC 相关编码的 JDBC 抽象层。
    ORM 模块为流行的对象关系映射 API,包括 JPA,JDO,hibernate 和 myBatis,提供集成层。
    OXM 模块提供了抽象层,它支持对 JAXB,Castor,XMLBeans,JiBX 和 XStream 的对象/XML 映射实现。
    Java 消息服务 JMS 模块包含生产和消费的信息的功能。
    事务模块为实现特殊接口的类及所有的 POJO 支持编程式和声明式事务管理。
     
     
    Web
    Web 层由 Web,Web-MVC,Web-Socket 和 Web-Portlet 组成,它们的细节如下:
    Web 模块提供了基本的面向 web 的集成功能,例如多个文件上传的功能和使用 servlet 监听器和面向 web 应用程序的上下文来初始化 IoC 容器。
    Web-MVC 模块包含 Spring 的模型-视图-控制器(MVC),实现了 web 应用程序。
    Web-Socket 模块为 WebSocket-based 提供了支持,而且在 web 应用程序中提供了客户端和服务器端之间通信的两种方式。
    Web-Portlet 模块提供了在 portlet 环境中实现 MVC,并且反映了 Web-Servlet 模块的功能。
     
     
    其他
    还有其他一些重要的模块,像 AOP,Aspects,Instrumentation,Web 和测试模块,它们的细节如下:
    AOP 模块提供了面向方面的编程实现,允许你定义方法拦截器和切入点对代码进行干净地解耦,它实现了应该分离的功能。
    Aspects 模块提供了与 AspectJ 的集成,这是一个功能强大且成熟的面向切面编程(AOP)框架。
    Instrumentation 模块在一定的应用服务器中提供了类 instrumentation 的支持和类加载器的实现。
    Messaging 模块为 STOMP 提供了支持作为在应用程序中 WebSocket 子协议的使用。它也支持一个注解编程模型,它是为了选路和处理来自 WebSocket 客户端的 STOMP 信息。
    测试模块支持对具有 JUnit 或 TestNG 框架的 Spring 组件的测试。
     
    spring之IOC?
     
    IoC容器,最主要的就是完成对象的创建以及维护对象的依赖关系等。
    所谓控制反转,包括两部分:一是控制,二是反转,就是把传统方式需要由代码来实现对象的创建、维护对象的依赖关系,反转给容器来帮忙管理和实现。所以我们必须要创建一个容器,同时需要一种描述来让容器创建对象与对象的关系。
     
    一、控制(首先要有容器)
    首先,对于一个web应用,其部署在web容器中,web容器提供其一个全局的上下文环境,这个上下文就是ServletContext,其为后面的spring IoC容器提供宿主环境;
    其次,在web.xml中会提供有contextLoaderListener。在web容器启动时,会触发容器初始化事件,此时contextLoaderListener会监听到这个事件,其contextInitialized方法会被调用,在这个方法中,spring会初始化一个启动上下文,这个上下文被称为根上下文,即WebApplicationContext,这是一个接口类,确切的说,其实际的实现类是XmlWebApplicationContext。这个就是spring的IoC容器,其对应的Bean定义的配置由web.xml中的context-param标签指定。在这个IoC容器初始化完毕后,spring以WebApplicationContext.ROOTWEBAPPLICATIONCONTEXTATTRIBUTE为属性Key,将其存储到ServletContext中,也就是web容器。web容器也是map集合的方式管理spring的容器的。便于获取;
    1:Spring容器究竟是什么?
    a:Spring容器是Spring的核心,一切Spring bean都存储在Spring容器内,并由其通过IoC技术管理。Spring容器也就是一个bean工厂(BeanFactory)。应用中bean的实例化,获取,销毁等都是由这个bean工厂管理的。
    b:ApplicationContext接口用于完成容器的配置,初始化,管理bean。一个Spring容器就是某个实现了ApplicationContext接口的类的实例。
     
    1、FileSystemXmlApplicationContext类
    这个方法是从文件绝对路径加载配置文件,例如:
    ApplicationContext ctx = new FileSystemXmlApplicationContext( "G:/Test/applicationcontext.xml ");
    如果在参数中写的不是绝对路径,那么方法调用的时候也会默认用绝对路径来找,我测试的时候发现默认的绝对路径是eclipse所在的路径。
    采用绝对路径的话,程序的灵活性就很差了,所以这个方法一般不推荐。
    (如果要使用classpath路径,需要加入前缀classpath:   )
     
    2、ClassPathXmlApplicationContext类
    这个方法是从classpath下加载配置文件(适合于相对路径方式加载),例如:
    ApplicationContext ctx = new ClassPathXmlApplicationContext( "/applicationcontext.xml ");
    该方法参数中classpath: 前缀是不需要的,默认就是指项目的classpath路径下面;这也就是说用ClassPathXmlApplicationContext时默认的根目录是在WEB-INF/classes下面,而不是项目根目录。这个需要注意!
     
    3、XmlWebApplicationContext类
    专为web工程定制的方法,推荐Web项目中使用。WebApplicationContext需要ServletContext实例,也就是说它必须拥有Web容器的前提下才能完成启动的工作.例如:
    ServletContext servletContext = request.getSession().getServletContext();
    ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);
     
    spring分别提供了用于启动WebApplicationContext的Servlet和Web容器监听器:
    org.springframework.web.context.ContextLoaderServlet;
    org.springframework.web.context.ContextLoaderListener.
    这两个方法都是在web应用启动的时候来初始化WebApplicationContext,我个人认为Listerner要比Servlet更好一些,因为Listerner监听应用的启动和结束,而Servlet得启动要稍微延迟一些,如果在这时要做一些业务的操作,启动的前后顺序是有影响的。
     
    配置例子如下:
    context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value>/WEB-INF/applicationContext.xml</param-value> 
    </context-param> 
    <listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
    </listener>
     
     
     
    2:容器的实例化:
    IoC容器是怎么完成初始化的以及对象创建的。Spring只需要三步:
    Ioc容器的初始化是由refresh()方法来启动的,这个方法标志着Ioc容器的正式启动
    refresh()方法可谓Spring的核心的入口函数,Spring容器的初始化正是由此开始。。
    具体来说这个启动过程包括三个基本过程:
    1.BeanDifinition的Resource定位
    2.BeanDifinition的载入与解析
    3.BeanDifinition在Ioc容器中的注册
     
    需要注意的是,Spring把这三个过程分开,并使用不同的模块来完成,如使用相应的ResourceLoader、BeanDifinitionReader等模块,通过这样的实际方式,可以让用户更加灵活的对这三个过程进行剪裁和扩展。
    定义出最适合自己的Ioc容器的初始化过程。
     
    第一个过程:BeanDifinition的Resource定位
    编程的方式使用DefaultListableBeanFactory时,首先定义一个Resource来定位容器使用的BeanDefinition。这时使用的是ClassPathResource,这意味着Spring会在类路径中去寻找以文件形式存在的BeanDefinition信息。
    这个Resource定位指的是BeanDifinition的资源定位,它由ResourceLoader通过统一的Resource接口来完成,这个Resource对各种形式的BeanDifinition的使用都提供了统一的接口。
    对于这些BeanDifinition的存在形式,相信大家都不会感到陌生。比如,
    在文件系统中的Bean定义信息可以使用FileSystemResource来进行抽象。
    在类路劲中的Bean定义信息可以使用ClassPathResource。
    这个定位过程类似于容器寻找数据的过程,就想水桶装水先要把水找到一样。
     
    第二个过程:BeanDifinition的载入
    这个载入过程是把用户定义好的Bean表示成Ioc容器内部的数据结构,而这个容器内部的数据结构就是BeanDifinition。具体来说,BeanDifinition实际上就是POJO对象在IOC容器中的抽象,通过这个BeanDifinition定义的数据结构,使IOC容器能够方便的对POJO对象也就是Bean进行管理。
     
    第三个过程:BeanDifinition的注册
    这个操作是通过调用BeanDifinitionRegistry借口来实现的。这个注册过程把载入过程中解析得到的BeanDifinition向Ioc容器进行注册。在阅读源码中可知,在IOC容器内部将BeanDifinition注入到一个HashMap中去,Ioc容器就是通过这个HashMap来持有这些BeanDifinition数据的。
     
    这里说到的Ioc容器的初始化过程,一般不包含Bean依赖注入的实现。在Ioc的设计中,Bean定义的载入和依赖注入是俩个独立的过程。依赖注入一般发生在应用第一次通过getBean向容器索取Bean的时候。(使用预实例化的配置除外)容器初始化的时候会预先对单例和非延迟加载的对象进行预先初始化。其他的都是延迟加载是在第一次调用getBean 的时候被创建。
     
    二、反转(容器通过工厂创建Bean,再将Bean的注入)
     
    1:
    BeanFactory是顶层的一个接口类,只对IoC容器的基本行为作了定义或者是规范,没有具体实现。它有三个子接口:ListableBeanFactory、HierarchicalBeanFactory 和AutowireCapableBeanFactory。
     
    2 :
    ListableBeanFactory 提供容器内bean实例的枚举功能.这边不会考虑父容器内的实例.
    HierarchicalBeanFactory 提供父容器的访问功能
    AutowireCapableBeanFactory 定义 Bean 的自动装配规则。

     
    3:
    最终的实现类是: DefaultListableBeanFactory,我们就是通过它的以下方法获得Bean实例。
    ApplicationContext接口获取Bean方法简介
    1: Object getBean(String name) 根据名称返回一个Bean,客户端需要自己进行类型转换;
    2: T getBean(String name, Class<T> requiredType) 根据名称和指定的类型返回一个Bean,客户端无需自己进行类型转换,如果类型转换失败,容器抛出异常;
    3: T getBean(Class<T> requiredType) 根据指定的类型返回一个Bean,客户端无需自己进行类型转换,如果没有或有多于一个Bean存在容器将抛出异常;
    4: Map<String, T> getBeansOfType(Class<T> type) 根据指定的类型返回一个键值为名字和值为Bean对象的 Map,如果没有Bean对象存在则返回空的Map。
     
    GetBean 的大概过程:
    1.       先试着从单例缓存对象里获取。
    2.       从容器取, 从父容器里取定义,有则由父容器创建,再从子容器取定义......。
    3.       如果是单例,则走单例对象的创建过程:在 spring 容器里单例对象和非单例对象的创建过程是一样的。都会调用父类 AbstractAutowireCapableBeanFactory 的 createBean 方法。 不同的是单例对象只创建一次并且需要缓存起来。 DefaultListableBeanFactory 的父类 DefaultSingletonBeanRegistry 提供了对单例对象缓存等支持工作。所以是单例对象的话会调用 DefaultSingletonBeanRegistry 的 getSingleton 方法,它会间接调用AbstractAutowireCapableBeanFactory 的 createBean 方法。
    4: 如果是 Prototype 多例则直接调用父类 AbstractAutowireCapableBeanFactory 的 createBean 方法。
     
    bean 作用域
    单例作用域
    单例bean只会产生一个实例,对于所有的请求,Spring容器都只会返回一个实例,默认的作用域就是单例的。
    换句话说,当定义了单例bean,Srping容器只会创建一个实例,这个实例存储在单例池中,单例池应该属于缓存,接下来所有对于该单例bean的请求和引用,都将返回缓存中的对象。
    prototype原型作用域
    设置bean作用域为prototype,就是非单例,对于每次请求都将返回一个该类的新实例。也就是说,原型bean注入另一个bean,或者是请求原型bean,都是通过在容器上调用getBean()方法产生的。一般来说 ,原型bean用于有状态bean,单例bean用于无状态bean。
    Request, session, and global session scopes
    request
    ,session
    ,global session
    作用域,只有在spring web ApplicationContext
    的实现中(比如XmlWebApplicationContext
    )才会起作用,若在常规Spring IoC容器中使用,比如ClassPathXmlApplicationContext
    中,就会收到一个异常IllegalStateException
    来告诉你不能识别的bean作用域

  • 相关阅读:
    如何实现Iframe透明
    ListView(未完)
    我又回来了
    前言
    代码重用and思路重用
    图片上传
    千万数量级分页存储过程
    MSSQL中,将text,ntext转换为int型数据
    优秀的回复,来自圣殿骑士
    SqlDataSource控件
  • 原文地址:https://www.cnblogs.com/domi22/p/8047920.html
Copyright © 2011-2022 走看看