Spring 基础语法整理

Spring 基础语法整理

Spring 背景和优点

在我看来 Spring 的诞生和流行离不开 mvc 模式的推送,正因为mvc 直接依赖太严重,代码硬编码耦合,难以维护,虽然通过工厂模式可以一定程度解耦,但工厂类需要自己维护开发这里也会留下很多坑,这里还有一个又特殊又严重问题是事务管理,事务控制要放在Service层实现,但做事务控制的API必须借助于持久层API。因此当持久层技术发生改变时,Service组件的事务控制代码也需要修改,这就违背了桥接模式的初衷。所以要用到 Spring。

下载和安装 Spring

   - 下载Spring的压缩包 / Maven管理依赖包
   - 解压压缩包,得到3个子目录:
         docs:参考手和API文档。
         libs:包括Spring的每个模块的class、api文档、源码的JAR包。
         schema:包含了Spring的各种配置文件的语义约束文档:XML Schema。
   - 使用Spring最基本的JAR包: 21个JAR + common-logging的JAR包即可
   - 增加一个Spring配置文件,文件名不限。

Spring的核心 – 容器

BeanFactory => ApplicationContext => ClassPathXmlApplicationContext / FileSystemXmlApplicationContext

ApplicationContext:
  • ApplicationContext可以看做是BeanFactory的升级版,他可以预初始化容器中所有的singleton Bean(程序创建Spring容器时,会立即创建容器中的singleton Bean,并为之执行setter方法,如果希望关闭ApplicationContext的与初始化行为可为该Bean指定lazy-init="true"称懒加载)。
  • ApplicationContext继承MessageSource接口,提供国际化支持。
  • ApplicationContext还支持资源访问(Spring为资源访问提供的接口是Resource)。
  • ApplicationContext还提供了事件机制
  • 因为项目的应用发展,加载的配置不止一个,spring还提供了加载多个配置文件。
ApplicationContext.ClassPathXmlApplicationContext(String... configLocations)
ApplicationContext.FileSystemXmlApplicationContext(String... configLocations)

这里可以看到 spring 是通过工厂类去获取Spring容器,从容器里去获取 bean 从而达到解耦。而这些 bean 被获取的前提是这些bean 需要注入到 spring 的容器中,这种叫依赖注入。

依赖注入通常有3种:
  • 设值注入。通过调用setter方法注入属性值。
  • 构造注入。通过调用有参数构造器注入属性值。
  • 接口注入。

Spring的用法

依赖注入(IOC)

  • Spring的本质是通过 xml 来支配代码。
    • bean元素 :通过 ID(唯一标识符)找到对应容器,再驱动使用new调用构造器。 如果需调用有参数的构造器,就需要在元素元素里添加子元素,每个该元素代表一个构造器参数。

      • id:唯一标识,该属性可以指定多个别名,多个别名之间用英文逗号隔开。通过元素为已有的Bean指定别名,每个元素指定一个别名。
      • property: 驱动调用setter方法。 对象创建出来之后,立即就会被调用。
      • constructor-arg: 驱动调用有参数的构造器 (元素里value属性指定的值优先被当成String类处理。为了明确地指定该值的类型,可以指定type属性)。
        • 所需参数是标量类型:用value属性或value子元素、 p:传入值。
        • 所需参数是复合类型:有3种配置方式:
          A. 用ref属性或ref子元素、p:xxx-ref
          B. 用嵌套Bean传入值
          C. 使用自动装配。
          - 所谓自动装配,就是让容器根据某种规则,自动完成依赖注入(调用setter或有参数的构造器)。
          autowire属性可以接受如下值:
          - no:不使用自动装配。Bean依赖必须通过ref元素定义。这是默认的配置。
          - byName:根据setter方法名来自动装配。BeanFactory查找容器中全部Bean,找出其中id属性与setter方法名去掉set前缀后同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入,也不报错。
          - byType:根据setter方法形参类型来自动装配。BeanFactory查找容器中全部Bean,如果正好有一个Bean类型与setter形参类型匹配,就自动注入这个Bean;如果有多个这样的Bean,就抛出一个异常;如果没有找到匹配的Bean实例,则Spring不会进行任何注入,也不报错。
          - constructor:与byType类似,区别是用于构造注入的参数。如果BeanFactory中不是恰好有一个Bean与构造器参数类型相同,则会抛出一个异常。
          - autodetect:BeanFactory根据Bean内部结构,决定使用constructor或byType。如果找到一个默认的构造函数,那么就会应用byType。 如果采用这种策略,配置关系实在太不清楚了。
          除此之外,autowire-candidate=“false”,设置该Bean放弃作为自动装配的候选人。
    • 反之代码来支配Spring 容器也是可以的。
      在某些时候,Bean要实现某个功能,必须借助于Spring容器才能完成,此时就需要让该Bean获取Spring的引用。

      • Bean实现ApplicationContextAware接口。
      • Bean实现该接口中setApplicationContext()方法。

Bean的作用和生命周期

上述可以看出 spring 其实就是通过 xml 来注入bean到容器中,再通过实现工厂类去获取配置的容器从而达到解耦。为了更好的性能,Bean的生命周期就显得很重要:
Bean的作用域通过scope属性来指定,该属性支持如下属性值:

  • singleton:无论何时去获取该Bean,Spring返回的总是同一个实例。初始化即被创建,容器销毁跟着销毁。
  • prototype:无论何时去获取该Bean,Spring返回的总是新的一个实例。即每次程序需要时,就会被创建一个新的实例。当程序不再需要时,如果Bean失去了引用就等待垃圾回收。
  • request:在Web应用中在一次用户请求内是singleton的。
  • session:在Web应用中在一次用户会话内是singleton的。
  • global:只能在Portlet环境下使用。
    请求和会话的区别这种无脑问题,我再答下,请求的生命周期是针对一个客户端(说确切点就是一个浏览器应用程序)的一次请求,当请求完毕之后,请求里边的内容也将被释放。而会话的生命周期也是针对一个客户端,但是却是在别人设置的会话周期内(这个看具体设置),会话里边的内容将一直存在,即便关闭了这个客户端浏览器,session也不一定会马上释放掉的 。

依赖注入(AOP)

当频繁去注入相同的 bean 的时候或去实现某些方法像事物回滚,代码的耦合性还是会存在,但后续业务增加修改的时候,每个地方还是有坑,这个时候就需要一个统一的配置达到改一个地方给所有地方增强,Spring就提供了aop。

  • AOP实现可分为两类:
    • 静态AOP实现:AOP框架在编译阶段即实现对目标类的增强,生成静态的AOP代理类。以AspectJ为代表。
    • 动态AOP实现:AOP框架在运行阶段动态生成AOP代理(在内存中动态地生成AOP代理类),以实现对目标对象的增强。以Spring AOP为代表。
      很明显:静态AOP实现的性能(这里指内存消耗)更好:因为已经生成了代理类的class文件,直接运行这些class文件即可,因此运行时无需任何额外的处理。动态AOP需要在运行时额外生成AOP代理类,性能一般。 静态AOP实现需要特殊的编译器。
AspectJ
  • 相关概念
    • 切面(Aspect):业务流程运行的某个特定步骤,也就是应用运行过程的关注点,关注点可能横切多个对象,所以常常也称为横切关注点。
    • 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用,或者异常的抛出。Spring AOP中,连接点总是方法的调用。
    • 增强处理(Advice:通知、建议):AOP框架在特定的切入点执行的增强处理。处理有“around”、“before”和“after”等类型。
    • 切入点(Pointcut):可以插入增强处理的连接点。简而言之,当某个连接点满足指定要求(切入条件)时,该连接点将被添加增强处理,该连接点也就变成了切入点。
    • 引入:添加方法或字段到被处理的类。Spring允许引入新的接口到任何被处理的对象。
    • 目标对象:被AOP框架进行增强处理的对象,也被称为被增强的对象。如果AOP框架是通过运行时代理来实现的,那这个对象将是一个被代理的对象。
    • AOP代理:AOP框架创建的对象,简单地说,代理就是对目标对象的加强。Spring中的AOP代理可以是JDK动态代理,也可以是CGLIB代理。前者为实现接口的目标对象的代理,后者为不实现接口的目标对象的代理。
    • 织入(Weaving):将增强处理添加到目标对象中、并创建一个被增强的对象(AOP代理)的过程就是织入。织入有两种实现方式:编译时增强(例如AspectJ)和运行时增强(例如CGLIB)。Spring和其他纯Java AOP框架一样,在运行时完成织入。
  • 语法
    • 定义一个准备作为Aspect使用的类。
    • 将准备作为Aspect使用的类配置成Spring容器中的普通Bean
    • 将指定的Bean转换为Aspect
    • 中添加 、、 元素将指定方法转换为Advice或对应的5个注解。
    • 指定将Advice“织入”哪些目标方法的、哪个位置。通过pointcut或pointcut-ref指定Advice在哪些目标方法处织入。

本文纯属个人总结,如有错误请矫正。

你可能感兴趣的:(java,spring)