ioc简述(快速了解ioc及使用)

本文是自己的学习过程,仅用于自己知识点的总结,并没有高深的,巧妙的技术在里面,大佬请绕行

1.什么是spring

  • 什么是框架:大师写好的半成品
  • spring:不是某层的功能性框架;用于整合项目的项目
  • spring是一个开源的Java开发框架,它提供了一种全面的解决方案,用于构建企业级应用程序。Spring框架的设计理念是基于面向对象的编程思想和松耦合的架构原则,旨在简化Java应用程序的开发,并提供可扩展性和灵活性。

2.ioc的概念

  • IOC:Inversion of Control  控制反转
          把对象的创建、分配、销毁等所有工作不再有程序来实现 而是交给sping容器来管理
  • DI : Dependency Injection 依赖注入
          在运行时  通过反射动态的把项目需要的对象 注入到程序中
          
  • 依赖注入是实现控制反转的一种设计方法,并不是说依赖注入等于控制反转(Inversion of Control,IoC)。控制反转是思想,依赖注入是具体实现方式

什么是控制反转

  • 控制: 创建对象,对象的属性赋值,对象之间的关系管理。
  • 反转: 把原来的开发人员管理,创建对象的权限转移给代码之外的容器实现。 由容器代替开发人员管理对象。创建对象,给属性赋值。

3.ioc的优点

ioc的思想最核心的地方在于,资源不由使用资源的双方管理,而由不使用资源的第三方管理,这可以带来很多好处。

灵活性

为广泛使用的接口更改实现类更简单(例如,用生产实例替换模拟web服务)

更改给定类的检索策略更简单(例如,将服务从类路径移动到JNDI树)

添加拦截器很简单,只需在一个地方完成(例如,向基于JDBC的DAO添加缓存拦截器)

可读性

该项目有一个统一一致的组件模型,没有工厂(如DAO工厂)

如果没有依赖项查找代码(例如对JNDI InitialContext的调用),代码更简洁,也不会杂乱无章

可测试性

当依赖项通过构造函数或setter公开时,它们很容易替换mock

更容易的测试导致更多的测试

更多的测试会带来更好的代码质量、更低的耦合性和更高的内聚性

4.ioc的使用

4.1导入jar包

  • 创建java项目

  • 导入jar

com.springsource.org.apache.commons.logging-1.1.1.jar:日志系统
com.springsource.org.apache.log4j-1.2.15.jar::::::日志系统
org.springframework.asm-3.0.1.RELEASE-A.jar::::::字节码操作依赖的jar
org.springframework.beans-3.0.1.RELEASE-A.jar:::::javavbean操作的jar
org.springframework.context-3.0.1.RELEASE-A.jar::::spring辅助功能的jar:::验证/邮件
org.springframework.core-3.0.1.RELEASE-A.jar::::::spring核心
org.springframework.expression-3.0.1.RELEASE-A.jar:::spring表达式依赖的jar

4.2创建配置文件

  • 配置文件名可以随意—— 唯一可以随意填写的内容

<?xml version="1.0" encoding="UTF-8"?>
<!-- 引入dtd文件、scheam文件   为xml文件定义语法规则 -->
<!-- dtd::document type defined:::文档类型定义文件:::给xml文件定义规则:::标签、属性、嵌套关系 -->
<beans
    xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:p="http://www.springframework.org/schema/p"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
</beans>

4.3定义实体类

1 实现序列化接口:Serializable
2 属性私有化封装:private+getset方法
3 属性包装类类型
4 无参数的构造方法

4.4在配置文件中创建对象

  • 通过bean标签

  • 赋值

    赋值方式1:property标签

    调用无参数的构造方法创建对象,通过set方法给属性赋值

    赋值方式2:constructor-arg标签

    调用对用的有参方法创建对象,标签数量必须和构造方法一致,即必须有对应的构造方法。顺序可以不和构造方法的一致

<?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">
​
    方式1:
    <bean class="springDemo.Teacher" id="t1"> <!-- 相对于src-->
        <property name="tid" value="1001"/>
        <property name="tname" value="张三"/>
        <property name="tsex" value="女"/>
        <property name="tdy" value="false"/>
        <property name="tsalary" value="1569.15"/>
    </bean>
​
​
    方式2:
<!--    this.tid = tid;-->
<!--    this.tname = tname;-->
<!--    this.tsex = tsex;-->
<!--    this.tsalary = tsalary;-->
<!--    this.tdy = tdy;-->
    <bean class="springDemo.Teacher" id="t2"> <!-- 创建一个 springDemo.Teacher类型的对象:::-->
        <constructor-arg name="tsalary" value="3569.15"/>
        <constructor-arg name="tdy" value="false"/>
        <constructor-arg name="tid" value="1002"/>
        <constructor-arg name="tname" value="李四"/>
        <constructor-arg name="tsex" value="男"/>
       
    </bean>
</beans>

4.5启动类

  • 获取上下文对象的方式

    方式1:ClassPathXmlApplicationContext 类

    方式2:FileSystemXmlApplicationContext

package springDemo;
​
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
​
public class TestDemo {
    public static void main(String[] args) {
        // 1 获取上下文对象:::指定xml文件的位置::路径相对于src
        //ClassPathXmlApplicationContext相当于src
        ClassPathXmlApplicationContext context;
        context = new ClassPathXmlApplicationContext("springDemo/spring_ioc_01.xml");
        Teacher t1 = (Teacher) context.getBean("t1");//2 通过getBean方法获取标签创建的对象
        System.out.println(t1);
        context.close();//3 关闭
​
        //1 获取上下文对象:::指定xml文件的位置::路径相对于当前项目
        FileSystemXmlApplicationContext context1 =
                new FileSystemXmlApplicationContext("src/springDemo/spring_ioc_01.xml");
        //2 通过getBean方法获取标签创建的对象
        Teacher t2 = (Teacher) context1.getBean("t2");
        System.out.println(t2);
        context1.close();//3 关闭
    }
}

4.6对象关联

  • 通过 ref 属性来指定对应关联的bean

  • 如果关联的been 在其他配置文件中,在当前配置文件中通过import标签 导入需要的配置文件

  • 如果不导入,将会报错:无法解析 Bean 't1'

<?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">
   
    <!-- 给单值数据类型的属性赋值::value -->
    <!-- 给引用数据类型的属性赋值::ref -->
    <bean class="springDemo.Student" id="s1"> <!-- 相对于src-->
        <property name="sid" value="1001"/>
        <property name="sname" value="张三"/>
        <property name="sex" value="女"/>
        <property name="sage" value="18"/>
        <property name="score" value="85.2"/>
        
        <property name="teacher" ref="t1"/><!--对象关联,需要导入需要的配置文件,如果不导入,将会报错:无法解析 Bean 't1'-->
    </bean>
    <import resource="spring_ioc_01.xml"/><!--导入需要的Teacher t1的配置文件-->
</beans>

4.7集合数组类型的属性

  • 格式

 <!--  数据为单值数据类型  -->
   <property name=" 属性名字 ">
        <属性的类型  value-type="属性需要的数据类型">
            <value>值</value>
            <value>值</value>
            <value>值</value>
            <value>值</value>
        </属性的类型>
    </property>
    
    <!-- 如果值得类型是其他配置文件对象 则是对象关联-->
    <property name="属性名字">
        <属性的类型 value-type="test01.Student 属性需要的数据类型 ">
            <ref bean="值"/>
            <ref bean="值"/>
            <ref bean="值"/>
        </属性的类型>
    </property>
   
​
    <!-- 给map类型属性赋值:private Map<String, Integer> mapStrInt; -->
    <property name="mapStrInt">
        <map key-type="java.lang.String" value-type="java.lang.Integer">
            <entry key="k_1" value="111" />
            <entry key="k_2" value="112" />
            <entry key="k_3" value="113" />
            <entry key="k_4" value="114" />
        </map>
    </property>
  • 示例

<bean class="test01.Teacher" id="t1">
    <property name="tid" value="1"/>
    <property name="tname" value="高老师"/>
    <property name="tsalary" value="3500"/>
​
    <!-- 给基本类型数组赋值 private int[] arrInt;-->
    <property name="arrInt">
        <array value-type="int">
            <value>1001</value>
            <value>1002</value>
            <value>1003</value>
        </array>
    </property>
​
    <!-- 给引用类型数组赋值private Student[] arrStu; -->
    <property name="arrStu">
        <array value-type="test01.Student">
            <ref bean="s1"/>
            <ref bean="s2"/>
            <ref bean="s3"/>
        </array>
    </property>
​
    <!-- 给单值数据类型list赋值:private List<Integer> listInt; -->
    <property name="listInt">
        <list value-type="java.lang.Integer">
            <value>1001</value>
            <value>1003</value>
            <value>1005</value>
            <value>1007</value>
        </list>
    </property>
​
    <!-- 给引用数据类型list赋值:private List<Student> listStu; -->
    <property name="listStu">
        <list value-type="test01.Student">
            <ref bean="s1"/>
            <ref bean="s2"/>
            <ref bean="s3"/>
        </list>
    </property>
​
    <!-- 给set类型属性赋值:private Set<Integer> setInt; -->
    <property name="setInt">
        <set value-type="java.lang.Integer">
            <value>11011</value>
            <value>12011</value>
            <value>13011</value>
            <value>14011</value>
        </set>
    </property>
​
    <!-- 给map类型属性赋值:private Map<String, Integer> mapStrInt; -->
    <property name="mapStrInt">
        <map key-type="java.lang.String" value-type="java.lang.Integer">
            <entry key="k_11" value="111" />
            <entry key="k_12" value="112" />
            <entry key="k_13" value="113" />
            <entry key="k_14" value="114" />
        </map>
    </property>

4.8 bean的生命周期

  1. 创建对象:默认情况下上下文对象加载核心品种文件时 就创建所有的bean标签定义的对象
  2. 对象初始化:对象一旦创建 就立刻调用bean的init-method对应的方法 进行对象的初始化
  3. 调用对象:getBean方法执行时 获取此唯一对象
  4. 销毁对象:上下文对象调用close方法前:会调用bean的destroy-method 来销毁对象

4.9 懒加载

  1.  懒记载只针对于:scope=singleton单例

  2. 默认情况下:是立即加载:::核心配置文件一记载 bean就立刻创建对象

  3.  通过设置bean的lazy-init="true" 来指定在调用getBean方法时才创建对象 

    <?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 class="springDemo.Teacher" id="t1" init-method="init" destroy-method="destroy" lazy-init="true"> <!-- 相对于src-->
            <property name="tid" value="1001"/>
            <property name="tname" value="张三"/>
            <property name="tsex" value="女"/>
            <property name="tdy" value="false"/>
            <property name="tsalary" value="1569.15"/>
        </bean>
    
    </beans>

 5. ioc的缺点

  1. 创建对象的步骤变复杂了,不直观,对小白来说的更难。
  2. 因为使用反射来创建对象,所以在效率上会有些损耗。但相对于程序的灵活性和可维护性来说,这点损耗是微不足道的。
  3. 缺少IDE重构的支持,如果修改了类名,还需到XML文件中手动修改,这似乎是所有XML方式的缺憾所在。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring IOC(Inversion of Control,控制反转)是Spring框架的核心特性之一,它是一种设计模式,用于解耦和管理对象之间的依赖关系。在传统的编程模式中,对象的创建和依赖关系的管理通常由开发者手动完成,而在Spring IOC中,这些工作由Spring容器来完成。 在Spring IOC中,对象的创建和依赖关系的管理是通过配置文件或注解来实现的。开发者只需要定义好对象的类和依赖关系,然后交给Spring容器来管理。Spring容器会根据配置文件或注解的信息,自动创建对象并解决对象之间的依赖关系。 Spring IOC的主要优点包括: 1. 松耦合:通过IOC容器管理对象之间的依赖关系,减少了对象之间的直接依赖,提高了代码的灵活性和可维护性。 2. 可测试性:由于对象的创建和依赖关系的管理由IOC容器完成,可以方便地进行单元测试和集成测试。 3. 可扩展性:通过配置文件或注解,可以方便地添加、修改和删除对象及其依赖关系,而无需修改代码。 Spring IOC的实现方式有多种,包括XML配置、注解配置和Java配置等。其中,XML配置是最传统也是最常用的方式,通过在XML文件中定义Bean的配置信息来实现IOC。注解配置是一种更简洁和方便的方式,通过在类或方法上添加注解来实现IOCJava配置是一种基于Java代码的配置方式,通过编写Java类来配置Bean和依赖关系。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值