• 【SSM】Spring系列——IoC 控制反转


    文章目录

    02 IoC 控制反转

    • 控制反转IoC(Inversion of Control) 是一个概念,是一种思想。
    • 指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管理。
    • 控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值, 依赖的管理。
    • IoC 是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖注入。应用广泛。

    依赖

    classA 类中含有 classB 的实例,在 classA 中调用 classB 的方法完成功能,即 classA对 classB 有依赖。

    Ioc 的实现

    依赖注入:DI(Dependency Injection),程序代码不做定位查询,这些工作由容器自行完成。

    • 依赖注入 DI 是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。

    • Spring 的依赖注入对调用者与被调用者几乎没有任何要求,完全支持对象之间依赖关系的管理。

    • Spring 框架使用依赖注入(DI)实现 IoC。

    • Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。

    • Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使用“依赖注入”的方式来管理 Bean 之间的依赖关系。

    • 使用 IoC 实现对象之间的解耦和。

    2.1 基于 XML 的 DI

    2.1.1 开发工具准备

    开发工具: idea2020.1

    依赖管理: maven3.6.3

    jdk: 1.8及以上

    2.1.2 设置maven的本地仓库

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SEFAVCp8-1658153514964)(../../../../Pictures/Spring/wps230.png)]

    2.2 Spring的第一个程序

    实现步骤如下:

    1.1.1 创建maven项目

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dchUQ8hU-1658153514964)(../../../../Pictures/Spring/wps231.jpg)]

    2.2.1 引入maven依赖pom.xml

    <properties>   
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>   	
        <maven.compiler.source>1.8maven.compiler.source>   
        <maven.compiler.target>1.8maven.compiler.target>  
    properties>
    
    <dependencies>  
        <dependency>  
            <groupId>junitgroupId>  
            <artifactId>junitartifactId>   
            <version>4.11version> 
            <scope>testscope> 
        dependency>
           
        <dependency>   
            <groupId>org.springframeworkgroupId>  
            <artifactId>spring-contextartifactId>   
            <version>5.2.5.RELEASEversion>  
        dependency> 
    dependencies> 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    2.2.2定义实体类

    public class Student { 
        private String name;  
        private int age;  
        //无参构造方法是为spring提供创建对象 
        public Student() {    
            System.**out**.println("我是学生类的无参构造方法");  
        }   
        //setXXX方法是为spring提供进行赋值操作的  
        public void setName(String name) {   
            this.name = name;
        }  
        public void setAge(int age) { 
            this.age = age;  
        } 
        @Override   
        public String toString() { 
            return "Student{" +    
                "name='" + name + '\'' +   
                ", age=" + age +    
                '}'; 
        } 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    2.2.3 创建Spring的配置文件

    在 src/main/resources/目录现创建一个xml 文件,文件名可以随意,但 Spring 建议的名称为 applicationContext.xml。

    spring 配置中需要加入约束文件才能正常使用,约束文件是 xsd 扩展名。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4BkHVsDU-1658153514965)(../../../../Pictures/Spring/wps232.jpg)]

    :用于定义一个实例对象。一个实例对应一个 bean 元素。

    id:该属性是 Bean 实例的唯一标识,程序通过 id 属性访问 Bean,Bean 与 Bean 间的依赖关系也是通过 id 属性关联的。

    class:指定该Bean所属的类,注意这里只能是类,不能是接口。

    2.2.4 创建测试类

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EaA30XLq-1658153514965)(../../../../Pictures/Spring/wps233.jpg)]

    2.2.5 使用Spring创建非自定义的类

    spring 配置文件加入 java.util.Date 定义:

    <bean id="myDate" class="java.util.Date" />
    
    • 1

    MyTest 测试类中:

    调用 getBean(“myDate”); 获取日期类对象。

    2.3 容器接口和实现类

    2.3.1ApplicationContext 接口(容器)

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IQq8IqcJ-1658153514965)(../../../../Pictures/Spring/wps234.png)]

    ApplicationContext 用于加载 Spring 的配置文件,在程序中充当“容器”的角色。其实现类有两个。

    (1)配置文件在类路径下

    若 Spring 配置文件存放在项目的类路径下,则使用 ClassPathXmlApplicationContext 实现类进行加载。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ShFRzYJd-1658153514966)(../../../../Pictures/Spring/wps235.jpg)]

    (2)ApplicationContext容器中对象的装配时机

    ApplicationContext 容器,会在容器对象初始化时,将其中的所有对象一次性全部装配好。以后代码中若要使用到这些对象,只需从内存中直接获取即可。执行效率较高。但占用内存。Spring初始化对象时要使用无参的构造方法,切记保证类中有无参构造方法。

    (3)使用 spring 容器创建的 java 对象

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QVckImJv-1658153514966)(../../../../Pictures/Spring/wps236.jpg)]

    2.4 注入分类

    • bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。
    • 初始化是由容器自动完成的,称为注入。
    • 根据注入方式的不同,常用的有两类:set 注入、构造注入。

    2.4.1 set 注入(掌握)

    • set 注入也叫设值注入
    • 是指通过 setter 方法传入被调用者的实例。
    • 这种注入方式简单、直观,因而在 Spring 的依赖注入中大量使用。

    (1)简单类型

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EmpxKArM-1658325726818)(../../../../Pictures/Spring/wps237.jpg)]

    测试类:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FTDEV0ye-1658325726818)(../../../../Pictures/Spring/wps238.jpg)]

    还可以创建系统类的对象并赋值。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sFQg5Sjm-1658325726819)(../../../../Pictures/Spring/wps239.jpg)]

    (2)引用类型

    • 当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。
    • ref 的值必须为某 bean 的 id 值。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-irJyFJVf-1658325726819)(../../../../Pictures/Spring/wps240.jpg)]

    对于其它 Bean 对象的引用,使用标签的 ref 属性。

    测试方法:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2Zu5u0bO-1658325726819)(../../../../Pictures/Spring/wps241.jpg)]

    2.4.2 构造方法注入

    • 构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。
    • 即,使用构造器设置依赖关系。
    • 在实体类中必须提供相应参数的构造方法。

    constructor-arg:通过构造函数注入
    property:通过setxx方法注入。

    标签中用于指定参数的属性有:

    • Ø name:指定参数名称。
    • Ø index:指明该参数对应着构造器的第几个参数,从 0 开始。不过,该属性不要也行, 但要注意,若参数类型相同,或之间有包含关系,则需要保证赋值顺序要与构造器中的参数顺序一致。

    (1)使用构造方法的参数名称注入值

    //提供有参的构造方法为进行注入值 
    public Student(String myname, int myage) {  
        this.name = myname; 
        this.age = myage; 
    }
    public Student(String name, int age, School school) {  
        this.name = name;  
        this.age = age;
        this.school = school; 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    applicationContext.xml文件中:

      
    <bean id="school" class="com.bjpowernode.pojo.s03.School"> 
        <constructor-arg name="name" value="清华大学">constructor-arg>   
        <constructor-arg name="address" value="北京海淀区">constructor-arg> 
    bean>
    
     
    <bean id="stu" class="com.bjpowernode.pojo.s03.Student"> 
        <constructor-arg name="age" value="22">constructor-arg>   
        <constructor-arg name="name" value="张三">constructor-arg>  
        <constructor-arg name="school" ref="school">constructor-arg> 
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    测试类:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qozbuYkP-1658325726819)(../../../../Pictures/Spring/wps242.jpg)]

    (2)使用构造方法的参数索引下标注入值

     
    <bean id="stuindex" class="com.bjpowernode.pojo.s03.Student">  
        <constructor-arg index="1" value="22">constructor-arg>  
        <constructor-arg index="0" value="李四">constructor-arg>   
        <constructor-arg index="2" ref="school">constructor-arg> 
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    (3)不指定名称和下标索引的注入

    
    <bean id="stuno" class="com.bjpowernode.pojo.s03.Student">  
        <constructor-arg  value="李四">constructor-arg>  
        <constructor-arg  value="22">constructor-arg>   
        <constructor-arg  ref="school">constructor-arg> 
    bean>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    注意:此种方式的注入一定要按类中构造方法的参数的顺序来进行注入

    (4)注入系统的类

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nhQ8v0Wr-1658325726820)(../../../../Pictures/Spring/wps243.jpg)]

    2.4.3引用类型属性自动注入

    • 对于引用类型属性的注入,也可不在配置文件中显示的注入。
    • 可以通过为标签设置 autowire 属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。

    根据自动注入判断标准的不同,可以分为两种:

    • byName:根据名称自动注入
    • byType: 根据类型自动注入

    (1) byName方式自动注入

    • 当配置文件中被调用者 bean 的 id 值与代码中调用者 bean 类的属性名相同时,
      可使用byName 方式,让容器自动将被调用者 bean 注入给调用者 bean。
    • 容器是通过调用者的 bean类的属性名与配置文件的被调用者 bean 的 id 进行比较而实现自动注入的。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FaFuPgKj-1658325726820)(../../../../Pictures/Spring/wps244.jpg)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-SWZ4wisy-1658325726820)(../../../../Pictures/Spring/wps245.jpg)]

    (2) byType方式自动注入

    • 配置文件中被调用者 bean 的 class 属性指定的类,
      要与代码中调用者 bean 类的某引用类型属性类型同源。

    • 什么是同源类型:
      a.被注入的类型(Student中的school)与注入的类型是完全相同的类型
      b.被注入的类型(Student中的school父)与注入的类型(子)是父子类
      c.被注入的类型(Student中的school接口)与注入的类型(实现类)是接口和实现类的类型

      注意:在有父子类的情况下,使用按类型注入,就意味着有多个可注入的对象.此时按照名称进行二次筛选,选中与被注入对象相同名称的对象进行注入.
      
      • 1
    • 但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配哪一个了。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Pruc8XuJ-1658325726821)(../../../../Pictures/Spring/wps246.jpg)]
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-huz2qyCx-1658325726821)(../../../../Pictures/Spring/wps247.jpg)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6kjAH52u-1658325726821)(../../../../Pictures/Spring/wps248.jpg)]

    2.4.4 Spring创建对象的作用域

    • Spring容器创建的对象默认的作用域是单例模式的.
    • 单例模式的目的就是无论访问多少次,得到的都是同一个对象.
    • 例如各种开发工具基本上都是单例的存在.但画图的工具是非单例的模式.

    我们可以通过创建系统时间来验证Spring创建对象的默认单例模式.

    <bean id="mydate" class="java.util.Date" scope="singleton"> ===>单例模式  
         
    bean>
    
    • 1
    • 2
    • 3

    可以设置为非单例的方式:

    <bean id="mydate" class="java.util.Date" scope="prototype">===>非单例模式 
         
    bean>
    
    • 1
    • 2
    • 3

    测试代码:

    @Test public void testSpringStudent()throws Exception{  
        //创建容器对象并启动.自动完成容器中所有对象的创建,默认调用无参的构造方法. 
        //如果没有提供无参的构造方法,则容器炸掉  
        ApplicationContext ac = new ClassPathXmlApplicationContext("s04/applicationContext.xml");  
        Date date1 = (Date) ac.getBean("mydate"); 
        System.out.println("第一次取出的对象:"+date1);   
        System.out.println("********************");  
        Thread.sleep(3000); 
        Date date2 = (Date) ac.getBean("mydate"); 
        System.out.println("第二次取出的对象:"+date2); 
        System.out.println(date1==date2); 
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    运行结果:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZFubGv8K-1658325726822)(../../../../Pictures/Spring/wps249.jpg)]

    2.4.5项目案例

    案例:

    ​ 使用三层架构完成用户数据的增加操作.由Spring容器负责对象的创建与依赖注入.

    分析:

    ​ 在分层开发中,Spring管理controller,service,dao各层的实现类对象的创建及依赖管理。

    创建对象的思路分析:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1c0814t6-1658325726822)(../../../../Pictures/Spring/wps250.jpg)]

    项目结构:

    使用三层架构进行用户的插入操作.界面层,业务逻辑层,数据访问层(模拟).

    Spring会接管三层架构中哪些对象的创建?界面层的对象,业务逻辑层的对象,数据访问层的对象.

    非Spring接管下的三层项目构建:

    • 实体类com.bjpowernode.pojo
      • Users
    • 数据访问层com.bjpowernode.dao
      • UsersMapper.java(接口)
      • UsersMapperImpl.java(实现类)
    • 业务逻辑层com.bjpowernode.service
      • UsersService.java(接口)
      • UsersServiceImpl.java(实现类 )
    • 界面层com.bjpowernode.controller
      • UsersController.java(Servlet)—>创建一个普通类担当servlet的功能

    代码实现:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wCLWanwH-1658325726822)(../../../../Pictures/Spring/wps251.jpg)]

    2.5 基于注解的 DI(Dependency Injection)

    • 依赖注入:DI(Dependency Injection),DI 使用注解将不再需要在 Spring 配置文件中声明bean 实例。
    • Spring 中使用注解, 需要在原有 Spring 运行环境基础上再做一些改变。
    • 需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2l7pdvX2-1658325726822)(../../../../Pictures/Spring/wps252.jpg)]

    指定多个包的三种方式:

    1. 使用多个 context:component-scan 指定不同的包路径

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5ItuesZN-1658325726823)(../../../../Pictures/Spring/wps253.jpg)]

    1. 指定 base-package 的值使用分隔符

    分隔符可以使用逗号(,)或分号(;),还可以使用空格,不建议使用空格。

    使用逗号分隔:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-flfnDPgI-1658325726823)(../../../../Pictures/Spring/wps254.jpg)]

    使用分号分隔:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GzObLKQZ-1658325726823)(../../../../Pictures/Spring/wps255.jpg)]

    1. base-package 是指定到父包名

    base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到子包下级的子包。所以 base-package 可以指定一个父包就可以。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dy2hBP1M-1658325726824)(../../../../Pictures/Spring/wps256.jpg)]

    或者最顶级的父包

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FenLitci-1658325726824)(../../../../Pictures/Spring/wps257.jpg)]

    但不建议使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。指定到目标包和合适的。也就是注解所在包全路径。例如注解的类在 com.bjpowernode.beans 包中。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G874vOdL-1658325726824)(../../../../Pictures/Spring/wps258.jpg)]

    2.5.1常用注解

    (1)创建对象的注解

    • @Component :创建所有对象都可以使用此注解,除了控制器,业务逻辑层,数据访问层的对象
    • @Controller:创建控制器层的对象,此对象可以接收用户请求,返回处理结果
    • @Service:创建业务逻辑层的对象,此对象可施事务控制,向上给控制器返回数据,向下调用数据访问层
    • @Repository:创建数据访问层的对象 ,对数据库中的数据进行增删改查操作

    (2)给对象赋值的注解

    • @Value:给简单类型赋值
    • @Autowired:给引用类型按类型注入
    • @Qualifier:给引用类型按名称注入

    2.5.2定义Bean的注解@Component(掌握)

    需要在类上使用注解@Component,该注解的 value 属性用于指定该 bean 的 id 值。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nW84YIL6-1658325726824)(../../../../Pictures/Spring/wps259.jpg)]

    • @Component 都可以创建对象,但另外三个注解还有其他的含义,
    • @Service 创建业务层对象,业务层对象可以加入事务功能,
    • @Controller 注解创建的对象可以作为处理器接收用户的请求。
    • @Repository,@Service,@Controller 是对@Component 注解的细化,标注不同层的对象。
      即持久层对象,业务层对象,控制层对象。
    • @Component 不指定 value 属性,bean 的 id 是类名的首字母小写。
      在这里插入图片描述
      在这里插入图片描述

    2.5.3 简单类型属性注入@Value(掌握)

    需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。

    使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Gmz3ugIF-1658325726825)(../../../../Pictures/Spring/wps262.jpg)]

    2.5.4 byType自动注入@Autowired(掌握)

    • 需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配 Bean 的方式。
    • 使用该注解完成属性注入时,类中无需 setter。
    • 当然,若属性有 setter,则也可将其加到 setter 上。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9EgtPpsP-1658325726825)(../../../../Pictures/Spring/wps263.jpg)]

    @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。

    若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。

    注意:如果可注入的类型多于一个,则按名称进行二次匹配.如果有匹配到则注入,如果没有匹配到,则报错。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNk0Nrxk-1658325726826)(../../../../Pictures/Spring/wps264.jpg)]

    2.5.5 byName自动注入@Qualifier(了解)

    • 需要在引用属性上联合使用注解@Autowired 与@Qualifier。
    • @Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。
    • 类中无需 set 方法,也可加到 set 方法上。
    • 当有相同类型的多个实现类时,使用@qualifier就可以确定是哪个实现类了。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2aAvcS8d-1658325726826)(../../../../Pictures/Spring/wps265.jpg)]

    如果可注入的类型多于一个,则按名称进行匹配.如果有匹配到则注入,如果没有匹配到,则报错。

    总结:

    依赖注入的注解
    简单类型(8种基本类型+String)的注入
    @Value:用来给简单类型注入值

    引用类型的注入
    @Autowired:使用类型注入值,从整个Bean工厂中搜索同源类型的对象进行注入.
    同源类型也可注入.
    什么是同源类型:
    a.被注入的类型(Student中的school)与注入的类型是完全相同的类型
    b.被注入的类型(Student中的school父)与注入的类型(子)是父子类
    c.被注入的类型(Student中的school接口)与注入的类型(实现类)是接口和实现类的类型

    注意:在有父子类的情况下,使用按类型注入,就意味着有多个可注入的对象.此时按照名称进行二次筛选,选中与被注入对象相同名称的对象进行注入.

    @Autowired
    @Qualifier(“名称”):使用名称注入值,从整个Bean工厂中搜索相同名称的对象进行注入.

    注意:如果有父子类的情况下,直接按名称进行注入值.

    2.5.6 基于注解三层架构的项目改造

    在每个类上添加创建对象的注解@Controller,@Service,@Repository,
    每个需要依赖注入的成员变量使用按类型@Autowired依赖注入即可.

    UsersMapperImpl.java
    
    	@Repository 
        public class UsersMapperImpl implements UsersMapper {   
        @Override  
        	public int insert(Users users) {  
           		System.out.println(users.getName()+"增加成功!");  
            	return 1;  
        	}
        }
    
    
    UsersServiceImpl.java
    
    	@Service 
        public class UsersServiceImpl implements UsersService {
        //切记切记:一定会有数据访问层的对象,调用它完成底层数据库的操作
            @Autowired
            UsersMapper usersMapper;//= new UsersMapperImpl(); 
            @Override  
            public int insert(Users u) {   
                return usersMapper.insert(u); 
            } 
    	} 
    
    
    UsersController.java
    
    	@Controller
        public class UsersController { 
            //切记切记:一定会有业务逻辑层的对象,指向实现类 
            @Autowired 
            UsersService usersService;// = new UsersServiceImpl();  
            //完成控制器中的增加用户的方法  
            public int insert(Users users){  
                return usersService.insert(users); 
            } 
        } 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    2.5.7 注解@resource自动注入(了解)

    • Spring 提供了对jdk 中@Resource 注解的支持。
    • @Resource 注解既可以按名称匹配Bean, 也可以按类型匹配 Bean。
    • 默认是按名称注入。
    • 使用该注解,要求 JDK 必须是 6 及以上版本。
    • @Resource 可在属性上,也可在 set 方法上。

    (1)byType 注入引用类型属性

    @Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不能注入 bean, 则会按照类型进行 Bean 的匹配注入。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pPm6DGjM-1658325726826)(../../../../Pictures/Spring/wps266.jpg)]

    (2)byName注入引用类型属性

    @Resource 注解指定其 name 属性,则 name 的值即为按照名称进行匹配的 Bean 的 id。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gfj8KFME-1658325726827)(../../../../Pictures/Spring/wps267.jpg)]

    2.6 注解与XML的对比

    注解优点:

    • 方便
    • 直观
    • 高效(代码少,没有配置文件的书写那么复杂)

    注解弊端:

    • 以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的

    XML 方式优点:

    • 配置和代码是分离的
    • 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。

    XML 方式缺点:

    • 编写麻烦,效率低,大型项目过于复杂

    2.7 为应用指定多个Spring配置文件

    在实际应用里,随着应用规模的增加,系统中 Bean 数量也大量增加,导致配置文件变得非常庞大、臃肿。为了避免这种情况的产生,提高配置文件的可读性与可维护性,可以将

    Spring 配置文件分解成多个配置文件。

    2.7.1 拆分策略

    常见的拆分策略有按模块拆分和按层拆分,当然在实际工作中,会有更细的拆分方法。

    • 按模块拆分,例如用户模块
      applicationContext_user.xml,
      applicationContext_book.xml,
      每个xml文件中都包含相应的xxxController,xxxService,xxxDao的对象的创建。
    • 按层拆分,例如拆分成
      applicationContext_controller.xml,
      applicationContext_service.xml,
      applicationContext_dao.xml等,每个xml文件中有相关对象的创建,例如:applicationContext_controller.xml文件中包含userController,bookController等对象的创建。
      - [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-COyFATGV-1658325726827)(../../../../Pictures/Spring/wps268.jpg)]

    2.7.2 拆分后整合

    可以使用通配符进行整合。但此时要求父配置文件名不能满足所能匹配的格式,否则将出现循环递归包含。就本例而言,父配置文件不能匹配 applicationContext-.xml 的格式,即不能起名为applicationContext-total.xml。

    (1)使用一个总的配置文件整合

    多个配置文件中有一个总文件,总配置文件将各其它子文件通过引入。在 Java

    代码中只需要使用总配置文件对容器进行初始化即可。注意:可以使用通配符*进行批量整合。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xkXntu8p-1658325726827)(../../../../Pictures/Spring/wps269.jpg)]

    (2)在测试类中批量导入

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-i0i3uPRE-1658325726828)(../../../../Pictures/Spring/wps270.jpg)]

  • 相关阅读:
    第十四届蓝桥杯(Web应用开发)模拟赛1期-大学组
    汉罗塔汉洛塔c++,看不懂ni打我
    简历项目优化关键方法论-START
    Nodejs+vue网上鲜花店销售信息系统express+mysql
    Grafana dashboards as ConfigMaps
    java基于微信小程序的智能停车场管理系统+ssm+uinapp+Mysql+计算机毕业设计
    曲线艺术编程 coding curves 第八章 贝赛尔曲线(Bézier Curves)
    Windows11 VMware-Ubuntu-Android12 源码下载和编译
    【java学习—十】异常(1)
    [附源码]计算机毕业设计基于springboot的4s店车辆管理系统
  • 原文地址:https://blog.csdn.net/m0_61163395/article/details/125901660