spring之ioc容器


介绍

什么是spring-framework

Spring是分层的JavaSE/EE应用一站式的轻量级开源框架。以iocInverse of control)控制反转和AopAspect Oriented Programming)面向切面编程为核心 ,

  • Spring 是一个开源应用框架,旨在降低应用程序开发的复杂度。
  • 它是轻量级、松散耦合的。
  • 它具有分层体系结构,允许用户选择组件,同时还为 J2EE 应用程序开发提供了一个有凝聚力的框架。
  • 它可以集成其他框架,如 StructsHibernateEJB 等,所以又称为框架的框架。

相关jar

  • spring-core是Spring的核心工具包

  • spring-cji是核心包所需的依赖包,

  • spring-aopSpring的面向切面编程,提供AOP(面向切面编程)的实现

  • spring-beansSpring IOC的基础实现,包含访问配置文件、创建和管理bean

  • spring-context:在基础IOC功能上提供扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持

  • spring-expressionspring表达式语言,就像EL表达式一样的东西

  • commons-logging:这个是只是一个日志包

看下面官网给的一张spring框架的结构图:

Spring 模块

  • Spring 核心容器

    – 该层基本上是 Spring Framework 的核心。它包含以下模块:

    • Spring Core
    • Spring Bean
    • SpEL (Spring Expression Language)
    • Spring Context
  • 数据访问/集成

    – 该层提供与数据库交互的支持。它包含以下模块:

    • DBC (Java DataBase Connectivity)
    • ORM (Object Relational Mapping)
    • OXM (Object XML Mappers)
    • JMS (Java Messaging Service)
    • Transaction
  • Web

    – 该层提供了创建 Web 应用程序的支持。它包含以下模块:

    • Web
    • Web – Servlet
    • Web – Socket
    • Web – Portlet
  • AOP– 该层支持面向切面编程

  • Instrumentation – 该层为类检测和类加载器实现提供支持。

  • Test – 该层为使用 JUnitTestNG 进行测试提供支持。

  • 几个杂项模块:

    • Messaging – 该模块为 STOMP 提供支持。它还支持注解编程模型,该模型用于从 WebSocket 客户端路由和处理STOMP消息。
    • Aspects – 该模块为与 AspectJ 的集成提供支持。

优点

  1. 方便解耦,简化开发:
    Spring就是一个大工厂,可以将所有对象创建和依赖关系维护,交给Spring管理

  2. AOP编程的支持:
    Spring提供面向切面编程,可以方便的实现对程序进行权限拦截、运行监控等功能

  3. 声明式事务的支持:
    只需要通过配置就可以完成对事务的管理,而无需手动编程

  4. 方便程序的测试:
    SpringJunit4支持,可以通过注解方便的测试Spring程序

  5. 方便集成各种优秀框架:
    Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如:StrutsHibernateMyBatisQuartz等)的直接支持
    6.降低JavaEE API的使用难度:
    Spring JavaEE开发中非常难用的一些APIJDBCJavaMail、远程调用等),都提供了封装,使这些API应用难度大大降低

配置

  • xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="hello" class="com.cherry.Students">
        <property name="name" value="spring"/>
    </bean>
    </beans>
    //三种方式(第一种常用)
    //第一种立即创建对象,适合单例对象,从项目配置文件加载
    ApplicationContext contexta = new
    ClassPathXmlApplicationContext("spring-config.xml");
    //第二种从磁盘任意位置加载
    ApplicationContext contextb = new FileSystemXmlApplicationContext("C:\\Users\\17598\\Desktop\\spring-config.xml");
    //第三种半配置问价半注解的方式
    ApplicationContext contextc = new AnnotationConfigApplicationContext("spring-config.xml");
  • 注入

    1. 构造器注入

      springIOC容器默认通过无参构造器去new对象

      当参数为非字符串类型时,在配置文件中需要制定类型,如果不指定类型一律按照字符串类型赋值。

      当参数类型不一致时,框架是按照字符串的类型进行查找的,因此需要在配置文件中制定是参数的位置。

      <!-- 通过构造器参数索引方式依赖注入 -->
          <bean id="helloBeanByIndex" class="com.lyc.cn.day04.HelloImpl">
              <constructor-arg index="0" value="小张"/>
              <constructor-arg index="1" value="3"/>
          </bean>
          <!-- 通过构造器参数类型方式依赖注入 -->
          <bean id="helloBeanByType" class="com.lyc.cn.day04.HelloImpl">
              <constructor-arg type="java.lang.String" value="小李"/>
              <constructor-arg type="int" value="4"/>
          </bean>
          <!-- 通过构造器参数名称方式依赖注入 -->
          <bean id="helloBeanByName" class="com.lyc.cn.day04.HelloImpl">
              <constructor-arg name="name" value="小王"/>
              <constructor-arg name="age" value="5"/>
          </bean>
  1. setter注入

    student

    public class Student
    {
        private String name;
        private Address address;
        private String[] books;
        private List<String> hobbies;
        private Map<String,String> card;
        private Set<String> games;
        private String wife;
        private Properties info;
    }

    xml配置

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
        <bean id="address" class="com.cherry.Address">
            <property name="address" value="江西"/>
        </bean>
        <bean id="hello" class="com.cherry.Student">
            <!--普通注入-->
            <property name="name" value="spring"/>
            <!--引用注入-->
            <property name="address" ref="address"/>
            <!--数组注入-->
            <property name="books">
                <array>
                    <value>红楼梦</value>
                    <value>三国演义</value>
                    <value>西游记</value>
                </array>
            </property>
            <!--list注入-->
            <property name="hobbies">
                <list>
                    <value>听歌</value>
                    <value>打篮球</value>
                </list>
            </property>
            <!--map注入-->
            <property name="card">
                <map>
                    <entry key="123" value="123"/>
                </map>
            </property>
            <!--set注入-->
            <property name="games">
                <set>
                    <value>LOL</value>
                    <value>QQSpeed</value>
                </set>
            </property>
            <!--null注入-->
            <property name="wife">
                <null/>
            </property>
            <!--properties注入-->
            <property name="info">
                <props>
                    <prop key="学号">201826702013</prop>
                    <prop key="性别"></prop>
                </props>
            </property>
        </bean>
    </beans>
  2. 拓展方式,pc标签注入

    首先导入约束

    p-namespace : xmlns:p="http://www.springframework.org/schema/p"

    c-namespace : xmlns:c="http://www.springframework.org/schema/c"

    <!--c命名空间,通过构造器注入-->
        <bean id="user" class="com.cherry.User" c:name="小陈" c:age="18"/>
        <!--p命名空间,直接注入属性的值-->
        <bean id="user2" class="com.cherry.User" p:name="小王" p:age="18"/>
  3. 注解注入

  • 注解配置

    • @Component,配置bean,注在类上

      package com.cherry.module;
      
      import org.springframework.beans.factory.annotation.Value;
      import org.springframework.stereotype.Component;
      
      /**
       * @author Bryant
       */
      @Component("user")
      public class User
      {
          @Value("cherry")
          private String name;
      
          public User(String name)
          {
              this.name = name;
          }
      
          //注册为bean一定要有一个空的构造器
          public User()
          {
      
          }
      
          public String getName()
          {
              return name;
          }
      
          public void setName(String name)
          {
              this.name = name;
          }
      }
      • @Respository dao层
      • @Service service层
      • @Controller 控制层
    • @Scoope("singleton") 单例模式 prototype原型模式,注在属性或者setter方法上

    • Java配置

      完全使用注解,不需要xml配置文件。

      • @Configuration

        @Configuration
        public class JavaConfig
        {
            @Bean //方法的名字就是bean的id
            public User getUser()
            {
                return new User();
            }
        }
      • @Import (导入另一个javaconfig)

  • bean的作用域

    Scope Description
    singleton (Default) Scopes a single bean definition to a single object instance for each Spring IoC container.
    prototype Scopes a single bean definition to any number of object instances.
    request Scopes a single bean definition to the lifecycle of a single HTTP request. That is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
    session Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
    application Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
    websocket Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

    (1)当一个bean的作用域为Singleton,那么Spring IoC容器中只会存在一个共享的bean实例,并且所有对bean的请求,只要id与该bean定义相匹配,则只会返回bean的同一实例。Singleton是单例类型,就是在创建起容器时就同时自动创建了一个bean的对象,不管你是否使用,他都存在了,每次获取到的对象都是同一个对象。注意,Singleton作用域是Spring中的缺省作用域。要在XML中将bean定义成singleton,可以这样配置:

    <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" scope="singleton">

  (2)当一个bean的作用域为Prototype,表示一个bean定义对应多个对象实例。Prototype作用域的bean会导致在每次对该bean请求(将其注入到另一个bean中,或者以程序的方式调用容器的getBean()方法)时都会创建一个新的bean实例。Prototype是原型类型,它在我们创建容器的时候并没有实例化,而是当我们获取bean的时候才会去创建一个对象,而且我们每次获取到的对象都不是同一个对象。根据经验,对有状态的bean应该使用prototype作用域,而对无状态的bean则应该使用singleton作用域。在XML中将bean定义成prototype,可以这样配置:

   <bean id="account" class="com.foo.DefaultAccount" scope="prototype"/> 
   或者
<bean id="account" class="com.foo.DefaultAccount" singleton="false"/> 

  

  (3)当一个bean的作用域为Request,表示在一次HTTP请求中,一个bean定义对应一个实例;即每个HTTP请求都会有各自的bean实例,它们依据某个bean定义创建而成。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="loginAction" class="cn".csdn.LoginAction" scope="request"/>

  针对每次HTTP请求,Spring容器会根据loginAction bean的定义创建一个全新的LoginAction bean实例,且该loginAction bean实例仅在当前HTTP request内有效,因此可以根据需要放心的更改所建实例的内部状态,而其他请求中根据loginAction bean定义创建的实例,将不会看到这些特定于某个请求的状态变化。当处理请求结束,request作用域的bean实例将被销毁。

  (4)当一个bean的作用域为Session,表示在一个HTTP Session中,一个bean定义对应一个实例。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="userPreferences" class="com.foo.UserPreferences" scope="session"/>

  针对某个HTTP Session,Spring容器会根据userPreferences bean定义创建一个全新的userPreferences bean实例,且该userPreferences bean仅在当前HTTP Session内有效。与request作用域一样,可以根据需要放心的更改所创建实例的内部状态,而别的HTTP Session中根据userPreferences创建的实例,将不会看到这些特定于某个HTTP Session的状态变化。当HTTP Session最终被废弃的时候,在该HTTP Session作用域内的bean也会被废弃掉。

  (5)当一个bean的作用域为Global Session,表示在一个全局的HTTP Session中,一个bean定义对应一个实例。典型情况下,仅在使用portlet context的时候有效。该作用域仅在基于web的Spring ApplicationContext情形下有效。考虑下面bean定义:

<bean id="user" class="com.foo.Preferences "scope="globalSession"/>

global session作用域类似于标准的HTTP Session作用域,不过仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。

bean的自动装配

  • spring的装配方式

    1. xml显示配置
    2. java中显示配置
    3. 隐式的自动装配bean
  • 自动装配(引用类型)

    • ByName
    <!--
    byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的beanid!
    -->
    <bean id="cat" class="com.cherry.pojo.Cat" />
    <bean id="dog" class="com.cherry.pojo.Dog" />
    <bean id="people" class="com.cherry.pojo.People" autowire="byName">
        <property name="xiaohong"/>
    </bean>
    
    • ByType
    <bean id="cat" class="com.cherry.pojo.Cat" />
    <bean id="dog" class="com.cherry.pojo.Dog" />
    <bean id="people" class="com.cherry.pojo.People" autowire="byType">
        <property name="xiaohong"/>
    </bean>
    • constructor

    • 将ioc容器中的所有bean自动装配

      头文件中加 default-autowired =”byName”

      子标签bean可以覆盖这个自动装配

    byname的时候,需要保证所有bean的id唯一,并且这个bean需要和注入的属性的set方法的值一致

    bytype的时候,需要保证所有bean的class唯一,并且这个bean需要和注入的属性的类型一致

    • 注解自动装配
    1. 导入约束和对注解的支持

      <?xml version="1.0" encoding="UTF-8"?>
      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
      
        <context:annotation-config/>
      
      </beans>

      @Autowired

      参考:http://blinkfox.com/2018/09/17/hou-duan/spring/spring-ji-chu-jie-shao/


文章作者: 空指针异常
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 空指针异常 !
评论
  目录