Spring 笔记二 IOC

1、IOC

  IOC:Inversion  od  controller ,控制反转,控制的是资源的获取方式,由原来的自己创建 new 变成 Spring 容器创建。

  DI:Dependency  Injection,依赖注入。IOC是一种思想,DI是这种思想的具体实现。A 对象在完成一件任务时需要 B 对象,即 A 对象对 B 对象产生依赖,B 对象由容器创建,当 A 对象需要用 B 对象时,Spring 容器以某种方式将 B 对象注入到 A 对象。

2、IOC 容器

  

  在通过容器读取 bean 实例前,需要先将容器实例化。

  Spring 提供了两种容器实例化的方式。

  1.BeanFactory:面向 Spring 本身的,不是给开发人员使用的,通常使用下面这种方式。

  2.ApplicationContext:BeanFactory 的子接口,提供了更多高级特性,面向 Spring 的使用者。

  ApplicationContext 的主要实现类:

    ClassPathXmlApplicationContext:对应类路径下 xml 格式的配置文件。

    FileSystemXmlApplicationContext:对应磁盘下 xml 格式的配置文件。

  ApplicationContext 的主要子接口:

    ConfigurationApplicationContext:refresh()和close()方法提供了容器的启动、关闭和刷新上下文的方法。

3、Sping 程序的开发步骤

  Spring 程序的开发步骤

  1. 导包

    4个核心容器包+logging日志包

  2. 写配置文件

  3. 测试

4、实验

  实验1:通过IOC容器创建对象,并为属性赋值★

  

  细节:

    1. 默认创建的组件是单例的,单例对象是在容器创建完成的时候就创建好了,可以通过 scope指定对象的作用范围

    2. 可以通过 scope 属性设置组件的作用域,实验10演示。

    3. 通过 property 为属性赋值走的是set方法。

    4. scope 属性

      * singleton:默认值,单例的。

      * prototype:多例的。

      * request:web项目中,spring创建一个bean对象,将对象存入到request域中。

      * session:web项目中,spring创建一个bean对象,将对象存入到session域中。

      * global  session:web项目中,应用在 Portlet 环境,如果没有 Portlet 环境,那么 global session 相当于session。    

  实验2:根据bean的类型从IOC容器中获取bean的实例★

  

   细节:

    1. 如果同一个 bean 在配置文件中配置了多个,则获取时会报异常。

    NoUniqueBeanDefinitionException: No qualifying bean of type [com.moliao.pojo.Person] is defined: expected single matching bean but found 2: person,person2

    期望匹配单个bean,但找到了两个。

  实验3-1:通过构造器为bean的属性赋值(index,type属性介绍)

    

  实验3-2:通过p名称空间为bean赋值

   为了简化XML文件的配置,越来越多的XML文件采用属性而非子元素配置信息。Spring从2.5版本开始引入了一个新的p命名空间,可以通过<bean>元素属性的方式配置Bean的属性。

  语法:

  

  实验4-1:为属性赋null值

  

  细节:

    1.通过 value 给属性赋 null 值,只是给该属性赋值了"null"字符串,并不是真正的null。

  实验4-2:引用类型赋值(引用其他bean、引用内部bean)

    【1】引入外部已经声明的 bean

     

    【2】引入内部 bean

     

    细节:

      1. 该内部 bean 不能在外部使用。

  实验4-3: 集合类型赋值(List、Map、Properties)

    在Spring中可以通过一组内置的XML标签来配置集合属性,例如:<list>,<set>或<map>。

    【1】数组和List

    配置java.util.List类型的属性,需要指定<list>标签,在标签里包含一些元素。这些标签可以通过<value>指定简单的常量值,通过<ref>指定对其他Bean的引用。通过<bean>指定内置bean定义。通过<null/>指定空元素。甚至可以内嵌其他集合。

    数组的定义和List一样,都使用<list>元素。

     

     

    【2】Map

    通过<map>标签定义,<map>标签里可以使用多个<entry>作为子标签。每个条目包含一个键和一个值。

    必须在<key>标签里定义键。

    因为键和值的类型没有限制,所以可以自由地为它们指定<value>、<ref>、<bean>或<null/>元素。

    

    【3】Properties

    

  实验4-4:util 名称空间创建集合类型的bean

  如果只能将集合对象配置在某个bean内部,则这个集合的配置将不能重用。我们需要将集合bean的配置拿到外面,供其他bean引用。

  配置集合类型的bean需要引入util名称空间

  

  实验5:配置通过静态工厂方法创建的bean、实例工厂方法创建的bean、FactoryBean★

  【1】静态工厂

    调用静态工厂方法创建 bean 是将对象创建的过程封装到静态方法中。当客户端需要对象时,只需要简单地调用静态方法,而不用关心创建对象的细节。

   

   

  步骤:

    1. 声明通过静态方法创建的 bean 需要在 bean 的 class 属性里指定静态工厂类的全类名。

    2. 同时在 factory-method 属性里指定工厂方法的名称。

    3. 最后使用 <constrctor-arg> 元素为该方法传递方法参数。

  【2】实例工厂

    实例工厂方法:将对象的创建过程封装到另外一个对象实例的方法里。当客户端需要请求对象时,只需要简单的调用该实例方法而不需要关心对象的创建细节。

  

   

  步骤:

    1. 配置工厂类实例的bean

    2. 在factory-method属性里指定该工厂方法的名称

    3. 使用 construtor-arg 元素为工厂方法传递方法参数

  【FactoryBean】 

    1.  是Spring定义的一个接口类

    2.  实现了 FactoryBean 接口的类是 Spirng 可以认识的工厂类,Spring 会自动调用工厂方法创建对象。

    3.  接口中有三个方法

      ① getObject():返回创建的对象

      ② getObjectType():返回创建对象的类型

      ③ isSingleton():创建的对象是单例吗?true:是;false:不是。

     

     

  细节:

    1. 实现了 BeanFactory 的类,不管是单例还是多例,都是在获取时才创建对象。

  实验6:通过继承实现bean配置信息的重用 

    Spring允许继承bean的配置,被继承的bean称为父bean。继承这个父bean的bean称为子bean,子bean从父bean中继承配置,包括bean的属性配置,子bean也可以覆盖从父bean继承过来的配置。

    

  细节:

    1.父bean可以作为配置模板,也可以作为bean实例。若只想把父bean作为模板,可以设置<bean>的abstract 属性为true,这样Spring将不会实例化这个bean。

  实验10:创建带有生命周期方法的bean

  声明周期:bean 的创建到销毁。

  IOC 容器中注册的 bean:

    ① 单例 bean ,容器启动的时候创建,容器关闭的时候销毁。声明周期:对象创建>>对象初始化方法运行>>对象销毁方法运行

    ② 多例 bean ,获取的时候才创建。声明周期:获取时创建>>对象初始化,不会调用销毁方法。 

   

   

   细节:

    1. 初始化和销毁自定义的方法不能有参数。

  实验11:测试bean的后置处理器

   Spring 有一个接口,BeanPostProcessor,可以在 bean 初始化前后调用后置处理器方法。

  

  实验12:引用外部属性文件★

  当bean的配置信息逐渐增多时,查找和修改一些bean的配置信息就变得愈加困难。这时可以将一部分信息提取到bean配置文件的外部,以properties格式的属性文件保存起来,同时在bean的配置文件中引用properties属性文件中的内容,从而实现一部分属性值在发生变化时仅修改properties属性文件即可。这种技术多用于连接数据库的基本信息的配置。

  使用步骤:

  ① 创建 properties 属性文件

  

  ② 引入 context 名称空间

  

  ③ 指定 properties 属性文件位置

  

  ④ 引入属性值

  

  实验15:通过注解分别创建 bean★

  注解配置和 xml 配置要实现的功能都是一样的,都是要降低程序间的耦合。只是配置的形式不一样。

  注意:

    1. 在基于注解的配置中,我们还要多拷贝一个 aop jar 包 :spring-aop-4.0.0.RELEASE。

    2. 组件被上述注解标识后还需要通过 Spring 进行扫描才能够侦测到。<context:component-scan base-package="com.moliao"></context:component-scan>

      base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包及其子包中的所有类。      

      当需要扫描多个包时可以使用逗号分隔。 

  【1】用于创建对象的,相当于<bean id=" " class=" "></bean>

    ① @Component

      属性 value 用来指定 bean 的 id,不过不指定,默认是当前类的类名,首字母小写。  

    ② @Controller,用于表现层的注解  

    ③ @Service,用于业务层的注解

    ④ @Repository,用于持久层的注解

    细节:如果注解中有且只有一个属性要赋值时,且名称是 valuevalue 在赋值是可以不写。

  【2】用于注入数据的,相当于<property name=" " value=" ">;<property name=" " ref=" ">

    ① @Autowired:自动按照类型注入。当使用注解注入属性时, set 方法可以省略。它只能注入其他 bean 类型。当有多个
    类型匹配时,使用要注入的对象变量名称作为 bean id,在 spring 容器查找,找到了也可以注入成功。找不到就报错。

    ② @Qualifier:在自动按照类型注入的基础之上,再按照 Bean id 注入。它在给字段注入时不能独立使用,必须和
    @ @Autowire 一起使用;但是给方法参数注入时,可以独立使用。

    ③ @Resource:直接按照 Bean id 注入。它也只能注入其他 bean 类型。
    ④ @Value:注入基本数据类型和 String 类型数据的

  【3】用于改变作用范围的,相当于<bean id=" " class=" " scope=" ">

    ① Scope:指定 bean 的作用范围。

      value:指定范围的值。
      取值: singleton prototype request session globalsession

  【4】和生命周期相关的,相当于<bean id=" " class=" " init-method=" " destory-method=" ">

    ① @PostConstruct:用于指定初始化方法

    ② @PreDestory:用于指定销毁方法

  【5】总结

    

  实验18:使用 @Autowired 注解实现根据类型实现自动装配★

   Controller 组件中往往需要用到 Service 组件的实例,Service组件中往往需要用到 Repository 组件的实例。Spring可以通过 @Autowired 注解的方式帮我们实现属性的自动装配(注入)。

     【1】@ Autowired 原理:先按照类型去容器中找到对应的组件。

      ① 找到一个:自动赋值

      ② 找不到:报异常

      ③ 找到多个?装配上?

           按照变量名作为 id 继续匹配

          Ⅰ 匹配上:

          Ⅱ 没有匹配上:报异常,原因:按照变量名作为 id 匹配,找不到就报错。

            可以使用 @Qualifier 指定一个名作为 id 匹配。又有两种情况:

              Ⅰ 找到:装配上

              Ⅱ 找不到:报异常

   若某一属性允许不被设置,可以设置 @Autowired 注解的 required 属性为 false,这样不会报装配错误,但可能会有空指针。

   【2】@Autowired 作用到方法上

      ① 这个方法会在 bean 创建的时候自动运行

      ② 这个方法的每一个参数会自动注入值  

   【3】 @Autowired 和 @Resource区别:

      ① @Autowired 是spring的,@Resource 是java ee的。前者强大。

      ② @Resource 扩展性强。

  实验X:Spring 的单元测试

    第一步:导包:spring-test-4.0.0.RELEASE

    第二步:测试类上加注解:

       @ContextConfiguration:加载配置文件

       @RunWith:指定用哪种驱动进行测试,默认是junit,可以指定用 spring 的单元测试模块。

       

原文地址:https://www.cnblogs.com/_Moliao/p/13442276.html