spring入门笔记

控制反转: 把创建对象的权利交给框架,在使用过程中直接去得到这个对象;它包括依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup);

Spring 概况

  • Spring 是一个开源框架,为了解决企业应用开发的复杂性而创建的,但现在已经不止应用于企业应用。

  • 是一个轻量级的控制反转(IOC)和面向切面(AOP)编程的容器框架

    • 从大小和开销两方面而言 Spring 都是轻量的
    • 通过控制反转(IOC)的技术达到松耦合的目的
    • 提供了面向切面(AOP)编程的丰富的支持,允许通过分离应用的业务逻辑与系统级服务进行内聚性的开发
    • 包含并管理应用对象的配置和生命周期,这个意义上是一种容器 【它会管理由 Spring 它自己创建的对象,管理对象配置的信息以及这个对象的生命周期,也就是这个对象从创建到销毁都是由 Spring 自己来控制的】
    • 将简单的组件配置、组合成为复杂的应用,这个意义上是框架
Spring 作用
  • 容器
  • 提供了对多种技术的支持和集成
    • JMS
    • MQ支持
    • UnitTest
    • ...
  • AOP(事务管理、日志等)
  • 提供了众多方便应用的辅助类(JDBC Templatede等)
  • 对主流应用框架(Hibernate等)提供了良好的支持
Spring 适用范围
  • 构建企业应用(SpringMVC + Spring + Hibernate/ibatis、myBatis)
  • 单独使用Bean容器(Bean 管理)
  • 单独使用AOP进行切面的处理
  • 其他的 Spring 功能,如:对消息的支持等
  • 在互联网中的应用...

Spring-IOC 控制反转

接口及面向接口编程
  • 接口:

    • 用于沟通的中介物的抽象化【对外调用说明、规范】
    • 实体把自己提供给外界的一种抽象化说明,用以由内部操作分离出外部沟通方法,使其能被修改内部而不影响外界其他实体与其交互的方式【接口是对外的一种说明,说明了我会提供哪些功能,至于内部的实现,对外是不公开的;OC的.h文件也就类似于Java的接口】
    • 对应 Java 接口即声明,声明了哪些方法是对外公开提供的
    • Java 8 中,接口可以拥有方法体
  • 面向接口编程:

    • 结构设计中,分清层次及调用关系,每层只向外(上层)
    • 好处:接口实现的变动不影响各层级间的调用,这一点在向外或企业内部提供公共服务中尤为重要【稳定性】
    • “面向接口编程”中的“接口”是用于隐藏具体实现和实现多态性的组件
啥是IOC
  • IOC: 控制反转,控制权的转移,应用程序本省不负责依赖对象的创建和维护,而是由外部容器负责创建和维护;当我们需要一个对象的时候,不是去 new 一个,而是由外部容器创建,我们向外部容器去申请一个或者说拿来一个使用。

  • DI(依赖注入):是控制反转的一种实现方式 ;由 IOC 容器在运行期间,动态的将某种依赖关系注入到对象之中

  • 目的:创建对象并且组装对象之间的关系

Spring 的 Bean 配置
  1. 配置:在 spring-ioc.xml 中通过配置映射关系
  2. 使用:context.getBean(“配置的Bean的id”)拿到 Bean 对象,调用对应的方法
Bean 的初始化
  • 基础:两个包

    • org.springramework.beans : BeanFactory 提供配置结构和基本功能,加载并初始化Bean
    • org.springramework.context : ApplicationContext 保存了 Bean 对象并在 Spring 中被广泛使用
  • ApplicationContext 初始化方式:

    1. 加载本地文件

      FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("F:/workspace/appcontext.xml);
      
    2. Classpath 相对路径

      FileSystemXmlApplicationContext context = new FileSystemXmlApplicationContext("classpath:spring-context.xml);
      
    3. Web 应用中依赖 servlet 或 listener

      
          
              org.springframework.web.context.ContextLoaderListener
          
      
      
      
          context
          rg.springframework.web.context.ContextLoaderServlet
          1
      
      
      
Spring 常用注入方式

IOC 容器在加载的时候会扫描 xml 文件中 Bean 的相关配置,然后对这些 Bean 进行实例化

  • Spring 注入:是指在启动 Spring 容器加载 Bean 配置的时候,完成对变量的赋值行为【A里面有B,初始化A的时候同时对B进行赋值】

  • 注入方式

    • 设值注入:xml 配置 property 属性对应 Bean 的set方法
    • 构造注入:xml 配置 constructor-arg 属性对应 Bean 的构造方 法

Spring Bean

Bean 的配置项
* Id:在整个 IOC 容器中这个 Bean 的唯一标识
* Class:具体要实例化的哪一个类
* Scope:范围,作用域
* Constructor arguments:构造器的参数
* Properties:属性
* Autowiring mode:自动装配的模式
* lazy-initilizition mode:懒加载模式
* initilizition/destruction method:初始化和销毁的方法  

以上配置项共同构成了 Spring IOC 容器中对于 Bean 的配置,使用时理论上只有 Class 是必须的,其它的都可以不配置,但是想从 Bean 容器中得到某一个实例,两种方式:Id 和 Bean 的类型,如果根据 Id 获取,那么 Id 这一项就需要配置,如果是根据类型来获取就只需要获取 Class 这一项。  
Bean 的作用域 (scope)
  • singleton:单例,指容器中只存在一个 Bean 的实例【Spring bean 默认模式】
  • prototype:每次请求(每次使用)创建新的实例,destory 方式不生效

web 应用相关:

  • request:每次 http 请求创建一个实例仅在当前 request 内有效
  • sesion:同上,每次 http 请求创建,当前 session 内有效
  • global session:基于 portlet 的 web 中有效(portlet 定义了 global session),如果是在 web 中,同session。
Bean 的生命周期
  • 定义:Bean xml配置中 定义 id 和 class
  • 初始化:当 IOC 容器 context 启动的时候加载配置文件中的 Bean 并对其初始化【可单独或全局配置,三种方式】
  • 使用:从 Bean 容器中取出一个 Bean 的实例,然后去调用它的方法
  • 销毁:Bean 容器停止的时候销毁由当前这个 Bean 容器创建的所有的 Bean 的实例
Bean 的自动装配
  • NO: 不做任何操作【默认】
  • byName:根据属性名字自动装配。检查容器并根据名字查找与属性完全一致的 bean,并将其与属性自动装配。
    default-autowire=“byName”、依赖别的 Bean 的 Bean 中声明 set 方法 属性名字跟配置文件中的配置的id一样。
  • byType:如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配,如果存在多个该类型的bean,那么抛出异常,并指出不能使用 byType 类型进行自动装配;如果未找到相匹配的bean,那么将不做任何操作【跟上面一样 只不过根据 Bean 的类型来匹配,跟 配置文件里的 Bean 的id无关】
  • Constructor:与 byType 方式类似,不同之处在于它应用于构造器参数,如果容器中没有找到于构造器参数类型一致的 Bean 【无关id】,抛出异常
Resources&ResourcesLoader
  • 针对资源文件的统一接口【通过 Spring 加载一些资源文件的时候可以用 Resources 去完成】

Resources
- UrlResources:Url 对应的资源,根据 Url 地址即可构建
- ClassPathResources:获取类路径下的资源文件【相对路径】
- FileSystemResources:获取文件系统里面的资源【绝对路径】
- ServletContextResources:ServletContext封装的资源,用于访问ServletContext环境下的资源【和web相关】
- InputStreamResources:针对于输入流封装的资源
- ByteArrayResources:针对字节数组封装的资源

ResourcesLoader
对 Resources 进行加载,在 Spring 容器中,所有的 ApplicationContext 都实现了ResourcesLoader 这个接口,都可以获取 Resources 的实例,
Resources src = ctx.getResources(“资源路径”); classpath、file:、http:、

Bean 的自动装配 - Bean 的定义及作用域的注解实现
  1. Classpath 扫描与组件管理

    • 从 Spring3.0 开始,Spring JavaConfig 项目提供了很多特性,包括使用 java 注解而不是 xml 定义 Bean

    • @Component 是一个通用注解,可用于任何 bean

    • @Repository、@Service、@Controller 是 @Component 的子注解,是更有针对性的注解。

      • @Repository 通常用于注解 DAO 层,即持久层
      • @Service 通常用于注解 Service 类,即服务层
      • @Controller 通常用于注解 Controller 类,即控制层(MVC)
    • 注解到类上 Spring 可以自动检测类并注册 Bean 到 ApplicationContext 上

    • 默认情况下,类被发现并注册 bean 的条件是:使用 @Component、@Repository、@Service、@Controller 注解或使用 @Component 的自定义注解。

    • @scope:通常情况下自动查找的 Spring 组件,其 scope 是 singleton,Spring 2.5提供了一个标识scope的注解 @scope(“xxx”)【使用场景:在每一个线程中使用一个 bean 的实例】

    • @Required:表示受影响的 Bean 属性必须在配置时被赋值【不常用】

    • @AutoWired(自动注入):可以理解为一个传统的 set 方法,可以用于变量、set方法、构造方法【常用;默认下,如果因找不到合适的 Bean 将会导致 AutoWired 失败,抛出异常;使用前提,配置扫描的范围

    • @qualifier:使用在 成员变量、方法参数上 作用:缩小范围

  2. 基于 Java 容器的注解

    • @Bean:类似于XMl配置文件中的 ,配合@Configuration注解使用
    • @ImportResource:引入一个资源
    • @Value(“${属性名}”):获取资源文件中的内容
    • 妈蛋。。。

AOP 概述

AOP:(Aspect Oriented Programming),面向切面编程,通过预编译方式 & 运行期动态代理实现程序功能的统一维护的一种技术。

主要功能:日志统计,性能统计,安全验证,事务处理,异常处理等。

AOP(Aspect Oriented Programming),即面向切面编程,可以说是OOP(Object Oriented Programming,面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来建立一种对象层次结构,用于模拟公共行为的一个集合。不过OOP允许开发者定义纵向的关系,但并不适合定义横向的关系,例如日志功能。日志代码往往横向地散布在所有对象层次中,而与它对应的对象的核心功能毫无关系对于其他类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting),在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

AOP技术恰恰相反,它利用一种称为"横切"的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其命名为"Aspect",即切面。所谓"切面",简单说就是那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块之间的耦合度,并有利于未来的可操作性和可维护性。

使用"横切"技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处基本相似,比如权限认证、日志、事物。AOP的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。

切面是和功能垂直的

AOP实现方式:

  • 预编译
    • AspectJ
  • 运行期动态代理(JDK动态代理,CGlib动态代理)
    • SpringAOP,JbossAOP

相关概念:

  • 切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象,多个对象执行过程中,都会被该切面控制。

  • 连接点(Joinpoint):程序执行过程中的某个特定的点,【比如一个类中一个方法执行的开始】

  • 通知(Advice):在切面的某个特定的连接点上执行的动作【方法执行开始的时候额外执行的切面的动作】

    • 前置通知(before advice): < aop:before pointcut-ref=“” method=“” />
    • 返回之后的通知(after returning advice): < aop:after-returning pointcut-ref=“” method=“”/>
    • 异常后通知(after throwing advice):
    • 返回通知(after(finally)advice):< aop:after pointcut-ref=“” method=“”/>【方法结束前的最后一行代码】
    • 环绕通知(Around advice):通知方法的第一个参数必须是 ProceedingJoinPoint类型;< aop:around>
    • 簡介(introductions):简介允许一个切面声明一个实现指定接口对象的通知,并且提供了一个接口实现类来代表这些对象
  • 切入点(PointCut):匹配连接点的断言,在AOP中通知和一个切入点表达式关联【如何在切面中匹配一个具体的连接点】【切入时机】【方式贼多,需要配置】

  • 引入(Introduction):在不修改类代码的前提下,为类添加新的方法和属性

  • 目标对象(Target Object):被一个或多个切面所通知的对象

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

  • 织入(Weaving):把切面连接到其他的应用程序类型或者对象上,并创建一个被通知的对象,分为:编译时织入,类加载时织入,执行时织入【把切面和对象关联起来】

Spring AOP 实现:

  • 纯 java 实现,无需特殊的编译过程,不需要控制类加载器层次
  • 目前只支持方法执行连接点(通知 Spring Bean 的方法执行)
  • 不是为了提供最完整的 AOP 实现;而是侧重于提供一种 AOP 实现和 Spring IOC 容器之间的整合。
  • 不会和 AspectJ(全面综合解决方案)竞争,不会提供全面综合的解决方案。

有接口和无接口Spring AOP 实现区别:

  • 有接口:默认使用标准的 JavaSE 动态代理作为AOP代理,这使得任何接口和任何接口集都可以被代理
  • 无接口:使用CGLib 代理(如果一个业务对象没有实现任何一个接口)

你可能感兴趣的:(spring入门笔记)