spring ioc

深坑

spring ioc 相关知识

spring的优点
  • 方便解耦,简化开发(spring 是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理)
  • AOP编程的支持(spring 提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能)
  • 声明式事务的支持(值需要通过配置就可以完成对事务的管理,而无需手动编程)
  • 方便程序的测试(Spring对Junit4支持,可以通过注解方便的测试Spring程序)
  • 方便集成各种优秀框架(Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架的直接支持,比如: Struts、Hibernate、MyBaits等)
  • 降低JavaEE API的使用难度(Spring 对JavaEE开发中非常难用的一些API(JDBC/JavaMail/远程调用),都提供了封装,使这些API应用难度大大降低)
概念
  • IOC(Inverse of Control)反转控制的概念,就是将原本在程序中手动创建 UserService对象的控制权交由Spring框架管理,简单来说,就是创建UserService对象控制权被反转到了Spring框架。
  • DI(Dependency Injection)依赖注入的概念,就是在Spring创建这个对象的过程中,将这个对象所依赖的属性注入进去。
  • DL(Dependency Lookup)依赖查找

IOC入门小案例

配置文件读取
  • ClassPathXmlApplicationContext: 用于加载默认配置文件夹下的 “applicationContext.xml” 文件
  • FileSystemXmlApplicationContext: 加载其他文件夹的配置文件 “applicationContext.xml” 文件
三种实例化Bean的方式
  • 使用类构造器实例化(默认无参数)
  • 使用静态工厂方法实例化(简单工厂模式)
  • 使用实例工厂方法实例化(工厂方法模式)

三种实例化案例

Bean的配置
  • id和name
    • 一般情况下,装配一个Bean时,通过指定一个id属性作为Bean的名称
    • id属性在IOC容器中必须是唯一的
    • 如果Bean的名称中含有特殊字符,就需要使用 name 属性(其他情况下 name 和 id 没什么区别)
  • class
    • class用于设置一个类的完全路径名称,只要作用是IOC容器生成类的实例以及反射
bean的作用域
类别 说明
singleton 在springIoc容器中仅存在一个Bean实例,Bean以单实例的方式存在(默认
prototype 每次调用getBean() 时都会返回一个新的实例
request 每次HTTP请求都会创建一个新的Bean,该作用域仅适用于WebApplicationContext环境
session 同一HTTP Session 共享一个Bean,不同的HTTPSession使用不同的Bean。该作用域仅适用于WebApplicationContext环境
Bean的生命周期配置

Spring初始化bean或销毁bean时,有时需要做一些处理工作,因此spring可以在创建和销毁bean的时候调用bean的两个生命周期方法。

/** * init-method:当bean被载入到容器的时候调用 * destory-method:从容器中删除的时候调用(scope=singleton有效),多例的情况spring不知道销毁的时候触发哪个 * 通过调用 ClassPathXmlApplicationContext 的 close() 方法触发销毁 **/ <bean id="xxx" class="...yyy" init-method="init" destory-method="destory"/>

Bean的生命周期案例

bean的生命周期过程 (最主要的是第5步~第8步,它可以对我们的类来进行增强,会涉及到aop理念)
  • 1)、instantiate bean对象实例化
  • 2)、populate properties 封装属性
  • 3)、如果Bean实例 BeanNameAware 执行 setBeanName
  • 4)、如果Bean实现 BeanFactoryAware 或者 ApplicationContextAware 设置工厂 setBeanFactory 或者上下文对象 setApplicationContext
  • 5)、如果存在类实现 BeanPostProcessor(后处理), 执行postProcessBeforeInitialization
  • 6)、如果Bean实现InitializingBean 执行 afterPropertiesSet
  • 7)、调用 指定初始化方法init
  • 8)、如果存在类实现BeanPostProcessor(处理Bean),执行postProcessAfterInitialization
  • 9)、执行业务处理
  • 10)、如果Bean实现 Disposable 执行 destroy
  • 11)、调用 执行自定义指定销毁方法

Bean的生命周期过程案例

生命周期 BeanPostProcessor 的作用

主要是为后期的AOP进行铺垫,它可以在我们类生成或实例化的过程当中通过 Proxy.newProxyInstance、method.invoke 进行增强。
BeanPostProcessor作用的案例

Spring的属性注入

对于类成员变量注入方式有三种 Spring 只支持前2种。

1)、构造方法注入
通过构造方法注入Bean的属性值或依赖的对象,它保证了 Bean 实例在实例化后就可以使用,构造器注入在<constructor_arg>元素里声明的属性。构造方法注入的案例

2)、属性setter方法注入,属性注入的案例

3)、p名称空间: 使用p命名空间是为了简化XML文件配置:

  • p:<属性名>=“xxx” 引入常量值
  • p:<属性名>-ref=“xxx” 引用其他Bean对象

p名称空间的案例

4)、SpEL注入
SpEL(spring expression language)是spring 表达式语言,可以用其他类的属性或方法来给另外一个类属性设置值,基本语法如下:

  • #{表达式}: 使用字符串
  • #{beanId}: 使用另一个bean
  • #{beanId.content.toUpperCase()}: 使用指定名属性,并使用方法
  • #{T(java.lang.Math).PI}: 使用静态字段或方法

SpEL基本注入的案例

5)、SpEL复杂类型的属性注入

  • 数组类型的属性注入
  • List集合类型的属性注入
  • Set集合类型的属性注入
  • Map集合类型的属性注入
  • Properties类型的属性注入

SpEL复杂类型注入的案例

6)、接口注入

使用注解定义Bean

Spring 在2.5版本开始引入使用注解去定义 Bean

  • @Component 描述Spring框架中Bean
  • @Repository 用于对DAO实现类进行标注
  • @Service 用于对Service实现类进行标注
  • @Controller 用于对Controller实现类进行标注

使用注解 Bean 示例

使用注解方式注入属性
  • 使用 @Autowired 进行自动注入(@Autowired默认按照类型进行注入,两个相同Beaan类型)
  • 使用 @Qualifier 指定注入Bean的名称
  • 使用 @Resource 和@Autowired功能类似,但强调使用名称注入,是上面2个注解功能之和

用注解方式注入属性示例

Spring的其他注解
  • @PostConstruct: 当bean被载入到容器的时候调用,相当于 init 方法。
  • @PreDestroy: 当bean从容器中删除的时候调用,相当于 destroy(scope=singleton有效) 方法。
  • @Scope: 用于指定Bean的作用范围

Spring的其他注解示例

传统XML配置和注解配置混合使用
  • XML 方式的优势在于解构清晰,易于阅读
  • 注解方式的优势在于开发便捷,属性注入方便
  • XML与注解的整合开发(XML 用于管理我们的类,注解用于完成里面的属性注入,这种整合方式来开发)
    • 引入 context命名空间
    • 在配置文件中添加 context:annotation-config标签

传统XML配置和注解配置混合使用示例