【Spring5:IOC的使用及原理解析】

Spring中的IOC容器

一、IOC底层原理与概念

  • 什么是IOC

    • 控制反转,将 对象创建对象之间的调用过程 教给Spring
    • 目的:为了降低耦合度
  • IOC底层原理

    • xml解析
    • 工厂模式
    • 反射
    原方式:image-20220718103402806
    演变->工厂设计模式:

    image-20220718103701371

    IOC现有过程:

    利用xml解析:获取文件路径

    反射:通过Class.forName(路径)获取创建对象

    image-20220718111000957

二、IOC接口(BeanFactory)

  • IOC思想基于IOC容器完成,IOC底层就是对象工厂
  • Spring提供IOC的实现接口
    • ApplicationContext
      • BeanFactory接口的子接口
      • 提供更加多的功能,供开发人员使用
      • 特点:加载配置文件xml的时候直接创建对象
    • BeanFactory
      • IOC容器最基本的实现方式(Spring内部进行使用,不提倡开发人员使用
      • *特点:加载配置文件xml的时候不会创建对象,获取对象的时候才创建配置文件
  • ApplicationContext的扩展接口实现类
    • ClassPathXmlApplicationContext:对应src下的工程路径
    • FileSystemXmlApplicationContext:电脑盘中的绝对路径
    • ConfigurableApplicationContext:扩展实现功能

三、IOC操作Bean管理 基于xml(底层原理机制,直接使用请跳过直接看 四)

  • Bean管理操作
    1. Spring创建对象
    2. Spring注入属性
  • 基于xml方式 创建对象
    • 在Spring配置文件中使用bean标签,标签添加对应内容,既可实现创建

    image-20220718113720216

    • bean标签属性

      • *id:对象的唯一标识
      • *class:类的全路径
    • 创建对象的时候,默认执行无参构造方法

  • 基于xml方式 注入属性*
    • DI:依赖注入,就是注入属性

      • 第一种方式:利用setter方法进行注入

        • 创建setter方法
        public void setAge(int age) {
            this.age = age;
        }
        
        public void setName(String name) {
            this.name = name;
        }
        
        • Spring配置文件中
        <!--配置User对象-->
        <bean id="user" class="test.User">
            <!--使用property标签完成属性的注入
            使用键值对的方法
            -->
            <property name="age" value="10"></property>
            <property name="name" value="lmz"></property>
        </bean>
        
      • 第二种方式:利用有参构造注入

        <!--通过有参构造方法配置-->
            <bean id="order" class="test.Order">
                <constructor-arg name="address" value="China"></constructor-arg>
                <constructor-arg name="id" value="1"></constructor-arg>
            </bean>
        
      • 设置空值()

       <constructor-arg name="address" >
       <null/>
       </constructor-arg>
      
      • 注入外部bean属性*

        • 例如:在Service层调用Dao层的实现类(方法同上)

        • 1.创建属性

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-MKoN2dwG-1658987323531)(https://s2.loli.net/2022/07/28/PXbnizYeEC2sGqS.png)]

        • 2.使用 ref 配置xml文件

          [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YncwlIid-1658987323532)(https://s2.loli.net/2022/07/28/aBJsqhUMRSPgorY.png)]

      • 注入内部bean

        • 内部bean:例如bean中有一对多关系:一个部门多个员工

          • 1.在bean中写好属性

          • 2.利用setter方法添加属性

            image-20220719100545568

      • 注入集合属性

        • 例如:有一个times类型的属性为int数组类型

          <!--数组类型的注入-->
          <property name="times">
              <array>
                  <value>1</value>
                  <value>10</value>
                  <value>11</value>
                  <!--map类型的注入标签为entry-->
              </array>
          </property>
          
        • 例如:有一个times类型的属性为对象(Course)数组类型

        image-20220719103557111

        • 将集合抽取,变为共有属性,需要时调用

        • <!--抽取list集合类型注入-->
          <util:list id="Psd">
              <value>dasda</value>
              <value>wqeqweqw</value>
          </util:list>
          <!--使用ref进行注入-->
          <property name="logPsd" ref="Psd"></property>
          
    • 工厂Bean的使用

      • 普通bean只能返回指定的类型
      <!--定义类型为User-->
      <bean id="user" class="test.User">
      
      //得到返回类型也是User
      User user = context.getBean("user", User.class);
      
      • 在xml里定义的bean类型可以和返回类型不一样

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LmqeitKR-1658987323533)(https://s2.loli.net/2022/07/28/4o1tbJlHq9sQijK.png)]

      其余步骤和xml配置一致

  • Bean的作用域
    • 在Spring中可以设置bean的实例是单实例还是多实例对象

      • 单实例:两次根据xml创建地址相同**(默认singleton)**

      • 多实例:两次根据xml创建地址不同**(prototype)**

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-XIr3LHHF-1658987323534)(https://s2.loli.net/2022/07/28/puDrEomN8dwKYCz.png)]

      • 放入到request或session中**(request/session)**

  • Bean的 生命周期
    1. 通过构造器创建bean实例(无参构造器中

    2. 设置bean的属性和其他bean的引用(set方法中

    3. 调用bean的初始化方法需要进行配置

      image-20220720092411155

    4. bean可以正常调用

    5. 容器关闭的时候,调用销毁方法(需要进行配置

      //1.加载配置文件
      ApplicationContext context
      =new ClassPathXmlApplicationContext("Bean1.xml");
      context.close();
      

      image-20220720092506543

  • xml 的自动装配

    • 定义:根据属性 名称 或 类型,Spring自动将匹配的属性注入

      • 根据名称**(byName)beanid值和属性名称一样**

        image-20220720095731019

      • 根据类型**(byType)**

        [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-weHNXaBB-1658987323536)(…/…/myimage/image-20220720095951759.png)]

  • 外部属性文件
    • 对比:直接配置数据库信息

      <!--直接配置连接池-->
      <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
          <property name="url" value="jdbc:mysql://localhost:3306/project"></property>
          <property name="username" value="root"></property>
          <property name="password" value="password"></property>
      </bean>
      
    • 从外部属性文件配置数据库连接池

      1. Properties文件引入Spring配置

        • 引入context名称空间

        image-20220720102945990

      2. 引入外部文件

        image-20220720111014175

四、IOC操作Bean管理 基于注解

  • 注解示例
    @myAnnotation(name="川泽")
    
    • 使用注解 可以简化xml配置
  • Spring针对Bean管理创建对象的注解
    1. @Component**(普通注解)**

    2. @Service**(建议在Service层)**

    3. @Controller**(建议在Web层)**

    4. @Repository**(建议在Dao层)**

      上面四个注解功能一样,都可以创建bean实例

  • 注解 创建Bean对象
    1. 引入Aop

      image-20220720112847506

    2. 开启组件扫描

      • 方式一

      image-20220720113639315

      • 方式二

        <!--方式二,指定父级目录下的 特殊注解进行扫描-->
            <!--
        		use-default-filters="false":不使用默认扫描方式
                type:扫描注解
                expression:扫描有Service标识的注解
            -->
        <context:component-scan base-package="test_annotation" use-default-filters="false">
            <context:include-filter type="annotation"
                                    expression="org.springframework.stereotype.Service"/>
        </context:component-scan>
        
    3. 创建类后在类上添加注解

      /**
       * 注解里面value值可以省略
       * 默认为类名,第一个字母小写
       */
      @Service(value = "userService") //相当于<bean id="userService" class="...">
      public class UserService {
          public void add_(){
              System.out.println("add");
          }
      }
      
  • Spring针对Bean管理注入属性的注解
    1. @Autowired:根据属性类型进行自动装配

    2. @Qualifier:根据属性名称进行注入

      • (需要和@Autowired一起使用)

        @Autowired//自动装配属性
        @Qualifier(value = "userDaoImp")//名称限制
        private UserDao userDao;
        
    3. @Resource:可以根据类型注入,可以根据名称注入(不推荐)

      @Resource//自动装配属性
      @Resource(value = "userDaoImp")//名称限制
      private UserDao userDao;
      
    4. @Value:注入普通类型

      @Value(value = "1")
      Integer a;
      
  • 注解 注入属性
    1. 创建属性

      image-20220721094809821

    2. 在Service层注入到对象,在属性上面使用注解

      image-20220721094947937

  • 纯注解开发(SpringBoot应用)
    1. 创建测试类,代替xml

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qnCARVTA-1658987323540)(https://s2.loli.net/2022/07/28/ALyuVvrj1XRBWHk.png)]

    2. 添加配置注解

      image-20220721102539682

    3. 调用时函数与 xml有所不同

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-C0bYtBJG-1658987323541)(https://s2.loli.net/2022/07/28/eOSxLB2obQZuGYU.png)]

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值