• Spring基础知识


    Spring是什么

      Spring是一个开源框架,是为了解决企业应用开发的的复杂性而创建的,但是现在已经不仅局限于企业应用。技术层面来说,Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架。它有以下的特点:

    ——轻量:大小、开销轻量
    ——通过IoC达到松耦合
    ——提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发
    ——包含并管理应用对象的配置和生命周期,在这个意义上来说是一种容器
    ——将简单的组件配置、组合成为复杂的应用,在这个意义上来说是一个框架
     
    Spring的IoC及Bean容器
    • 接口

      只能有声明不能有实现,支持多重继承(在java8中接口可以拥有方法体)

      抽象类:即可以有包含实现的声明也可以有不包含实现的声明

      类:声明必须包含实现 接口实现的变动不会影响其他各层的调用,对公共服务非常重要

    • IoC——控制反转
      控制反转:控制权的转移,应用程序本身不负责依赖对象的创建与维护,而是由外部容器负责创建和维护。
      依赖注入(DI):是一种实现方式,由IOC容器在运行期间,动态的将某种依赖关系注入到对象之中 目的:创建对象并且组装对象之间的关系
    • Spring的Bean的配置
      在IoC容器中将所有的控制对象称作bean,Spring对于bean的使用有两种方式:基于spring-ioc.xml的配置和注解。 注意xml中关于bean的配置程序段
    <bean id="oneInterface(自定义)" class="配置的实现类"></bean>
      使用示例:
    public void test(){
    OneInterface interface=super.getBean("oneInterface");//获取bean,不需要new对象
    interface.hello();//调用函数
    }
      首先想说说IoC(Inversion of Control,控制倒转)。这是spring的核心,贯穿始终。所谓IoC,对于spring框架来说,就是由spring来负责控制对象的生命周期和对象间的关系。这是什么意思呢,举个简单的例子,我们是如何找女朋友的?常见的情况是,我们到处去看哪里有长得漂亮身材又好的mm,然后打听她们的兴趣爱好、qq号、电话号、ip号、iq号………,想办法认识她们,投其所好送其所要,然后嘿嘿……这个过程是复杂深奥的,我们必须自己设计和面对每个环节。传统的程序开发也是如此,在一个对象中,如果要使用另外的对象,就必须得到它(自己new一个,或者从JNDI中查询一个),使用完之后还要将对象销毁(比如Connection等),对象始终会和其他的接口或类藕合起来。
      那么IoC是如何做的呢?有点像通过婚介找女朋友,在我和女朋友之间引入了一个第三者:婚姻介绍所。婚介管理了很多男男女女的资料,我可以向婚介提出一个列表,告诉它我想找个什么样的女朋友,比如长得像李嘉欣,身材像林熙雷,唱歌像周杰伦,速度像卡洛斯,技术像齐达内之类的,然后婚介就会按照我们的要求,提供一个mm,我们只需要去和她谈恋爱、结婚就行了。简单明了,如果婚介给我们的人选不符合要求,我们就会抛出异常。整个过程不再由我自己控制,而是有婚介这样一个类似容器的机构来控制。Spring所倡导的开发方式就是如此,所有的类都会在spring容器中登记,告诉spring你是个什么东西,你需要什么东西,然后spring会在系统运行到适当的时候,把你要的东西主动给你,同时也把你交给其他需要你的东西。所有的类的创建、销毁都由 spring来控制,也就是说控制对象生存周期的不再是引用它的对象,而是spring。对于某个具体的对象而言,以前是它控制其他对象,现在是所有对象都被spring控制,所以这叫控制反转。
      说完了IoC,那什么又是DI呢?DI的全称就做Dependency Injection,也叫依赖注入,一般是通过外接注入的方式来实现的,主要实现了解耦。DI实现解耦的方式通常有三种:构造器注入、属性设置器注入和接口注入。
      那么DI实现注入的原理又是什么呢? Java 1.3之后一个重要特征是反射(reflection),它允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性,spring就是通过反射来实现注入的。关于反射的相关资料请查阅java doc。
    • Spring注入
      是指在启动 Spring 窗口加载 bean 配置时完成对变量的赋值行为,常见有两种方式进行注入:
      设置注入:不需要显示地调用set方法,会根据xml的相关配置自动进行调用。
    <property name="xxx" ref="xxx"></property>

      构造注入:利用属性或成员变量的set方法进行注入 其中property里面的name是需要注入参数的成员变量的名称,ref是注入参数引入bean的名称

    <constructor-arg name="xxx" ref="xxx"></constructor-arg>

    Bean的配置及作用域

    • Bean的常用配置项(理论上只有class是必须的)
      id:唯一标识
      class:具体是哪一个类
      scope:范围
      constructor arguments:构造器的参数
      properties:属性
      Autowiring mode:自动装配模式
      lazy-initialization mode:懒加载模式
      initialization/destruction method:初始化/销毁的方法
    • Bean的作用域
      singletion 单例 bean容器只有唯一的对象(默认模式)
      prototype 每次请求会创建新的实例,destory方式不生效
      request 对于request创建新的实例,只在当前request内有效
      session 对于session创建新的实例,只在当前session内有效
      global session 基于portlet(例如单点登录的范围)的web中有效,如果在web中同session
     
    Bean的生命周期(定义,初始化,使用,销毁)
    • 初始化
      方法1.实现org.springframework.beans.foctory.InitializingBean接口,覆盖afterPropertiesSet方法。系统会自动查找afterPropertiesSet方法,执行其中的初始化操作
      方法2.配置init-method 例如设置bean中init-method="init"那么在初始化过程中就会调用相应class指定类的init()方法进行初始化工作
    • 销毁(与初始化类似)
      方法1.实现org.springframework.beans.foctory.DisposableBean接口,覆盖destory方法。
      方法2.配置destory-method
    • 配置全局初始化、销毁方法(属于默认配置)
      注意: 当三种方式同时使用时,全局(默认的)初始化销毁方法会被覆盖。
      另外实现接口的初始化/销毁方式会先于配置文件中的初始化/销毁方式执行。
      即使没有以上三种初始化方法也是可以编译执行的。
     
    Aware接口
    作用:实现了Aware接口的bean在初始化后可以获取相应资源并进行相应的操作
    举例: ApplicationContextAware:向实现了该接口的bean提供IOC容器的上下文信息(ApplicationContext),实现了该接口的bean必须配置到配置文件中并由spring的bean容器加载
    BeanNameAware:向实现了该接口的bean提供关于beanName定义的相关内容
     有以下的Aware接口
    • LoadTimeWeaverAware,加载Spring Bean时织入第三方模块,如AspectJ
    • BeanClassLoaderAware,加载Spring Bean的类加载器
    • BootstrapContextAware,资源适配器BootstrapContext,如JCA,CCI
    • ResourceLoaderAware,底层访问资源的加载器
    • BeanFactoryAware,声明BeanFactory
    • PortletConfigAware,PortletConfig
    • PortletContextAware,PortletContext
    • ServletConfigAware,ServletConfig
    • ServletContextAware,ServletContext
    • MessageSourceAware,国际化
    • ApplicationEventPublisherAware,应用事件
    • NotificationPublisherAware,JMX通知
    • org.springframework.beans.factory.BeanNameAware,声明Spring Bean的名字

    Bean的自动装配(AutoWiring)

    1.No:不做任何操作

    2.byname:根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配

    3.byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生

    4.Constructor:与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常

    Bean的自动装配:在beans标签配置属性 default-autowire="no/byName/byType/constructor" 作用为:省去了在Spring的xml中配置property标签和constructor-arg标签,只需要配置bean标签即可

    PS:byName和byType为设值注入,constructor为构造注入; byName要求bean标签的id属性需要和成员变量的名称一致, byType和constructor则跟id无关

     AOP
    • 什么是AOP

        AOP:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。 ·主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

    • 对切面的理解

         程序中的每一个模块或者说功能,任何一个模块中都要记录它的日志、事务、安全验证等等,给我们带来的工作量非常大。 当程序到达某种规模时,尤其是格式调整之类的,这种改动量是非常大的。如果通过切面方式,对开发人员是不可见的,默认地会对每一个子模块记录日志等这些工作。通过预编译或者动态代理的方式来执行这个功能, 对开发人员是透明,他不需要知道。 切面是和功能垂直的,也就是切面是横切与各个功能之上的

    • AOP实现方式

      ①预编译-AspectJ

      ②运行期动态代理(JDK动态代理、CGLib动态代理)-SpringAOP、JbossAOP

    • AOP几个相关概念

      ①切面---一个关注点的模块化,这个关注点可能会横切多个对象

      ②连接点--程序执行过程中的某个特定的点

      ③通知----在切面的某个特定的连接点上执行的动作

      ④切入点--匹配连接点的断言,在AOP中通知和一个切入点表达式关联

      ⑤引入----在不修改类代码的前提下,为类添加新的方法和属性

      ⑥目标对象-被一个或者多个切面所通知的对象

      ⑦AOP代理--AOP框架创建的对象,用来实现切面契约(包括通知方法执行等功能)

      ⑧织入---把切面连接到其他的应用程序类型或者对象上,并且创建一个被通知的对象,分为:编译时织入,执行时织入 Spring的AOP实现 ·纯java实现,无需特殊的编译过程·,不需要控制类加载器层次 ·目前只支持方法执行连接点(通知Spring Bean的方法执行) ·不是为了提供最完整的AOP实现(尽管它非常强大);而是侧重于提供一种AOP实现和Spring IOC容器之间的整合,用于帮助解决企业应用中的常见问题 ·Spring AOP不会与AspectJ竞争,从而提供综合全面的AOP解决方案。 有接口和无接口的Spring AOP实现区别 ·Spring AOP默认使用标准的JAVASE动态代理作为AOP代理,使得任何接口(或者接口集)都可以被代理 ·Spring AOP中也可以使用CGLIB代理(如果一个业务对象并没有实现一个接口)

    Spring的七大模块

    1. Spring Core: Core封装包是框架的最基础部分,提供IOC和依赖注入特性。这里的基础概念是BeanFactory,它提供对Factory模式的经典实现来消除对程序性单例模式的需要,并真正地允许你从程序逻辑中分离出依赖关系和配置。
    2.Spring Context: 构建于Core封装包基础上的 Context封装包,提供了一种框架式的对象访问方法,有些象JNDI注册器。Context封装包的特性得自于Beans封装包,并添加了对国际化(I18N)的支持(例如资源绑定),事件传播,资源装载的方式和Context的透明创建,比如说通过Servlet容器。
    3.Spring DAO:  DAO (Data Access Object)提供了JDBC的抽象层,它可消除冗长的JDBC编码和解析数据库厂商特有的错误代码。 并且,JDBC封装包还提供了一种比编程性更好的声明性事务管理方法,不仅仅是实现了特定接口,而且对所有的POJOs(plain old Java objects)都适用。
    4.Spring ORM: ORM 封装包提供了常用的“对象/关系”映射APIs的集成层。 其中包括JPAJDOHibernate 和 iBatis 。利用ORM封装包,可以混合使用所有Spring提供的特性进行“对象/关系”映射,如前边提到的简单声明性事务管理。
    5.Spring AOP: Spring的 AOP 封装包提供了符合AOP Alliance规范的面向方面的编程实现,让你可以定义,例如方法拦截器(method-interceptors)和切点(pointcuts),从逻辑上讲,从而减弱代码的功能耦合,清晰的被分离开。而且,利用source-level的元数据功能,还可以将各种行为信息合并到你的代码中。
    6.Spring Web: Spring中的 Web 包提供了基础的针对Web开发的集成特性,例如多方文件上传,利用Servlet listeners进行IOC容器初始化和针对Web的ApplicationContext。当与WebWork或Struts一起使用Spring时,这个包使Spring可与其他框架结合。
    7.Spring Web MVC: Spring中的MVC封装包提供了Web应用的Model-View-Controller(MVC)实现。Spring的MVC框架并不是仅仅提供一种传统的实现,它提供了一种清晰的分离模型,在领域模型代码和Web Form之间。并且,还可以借助Spring框架的其他特性。
  • 相关阅读:
    HDU5792 World is Exploding(树状数组)
    POJ3415 Common Substrings(后缀数组 单调栈)
    POJ2406 Power Strings(KMP,后缀数组)
    HDU5489 Removed Interval(动态规划)
    HDU1899 Sum the K-th's(树状数组)
    Codeforces Round #363 Fix a Tree(树 拓扑排序)
    数组-07. 求一批整数中出现最多的个位数字
    数组-06. 找出不是两个数组共有的元素
    数组-05. 字符串字母大小写转换
    数组-04. 查找整数
  • 原文地址:https://www.cnblogs.com/waliwaliwa/p/6802353.html
Copyright © 2020-2023  润新知