Spring-IOC

Spring

概述

Spring 是于 2003 年兴起的一个轻量级的 Java 开发框架,它是为了解决企业应用开发的复杂性而创建的。

Spring 的核心是控制反转(IoC)和面向切面编程(AOP)。Spring 是可以在 Java SE/EE 中使用的轻量级开源框架。

官网:https://spring.io

主要作用:

​ Spring 的主要作用就是为代码“解耦”,降低代码间的耦合度。就是让对象和对象(模块和模块)之间关系不是使用代码关联,而是通过spring配置来说明。即在 Spring 中说明对象(模块)的关系。

功能特点:

​ Spring 根据代码的功能特点,使用 Ioc 降低业务对象之间耦合度。IoC 使得主业务在相互调用过程中,不用再自己维护关系了,即不用再自己创建要使用的对象

了。而是由 Spring容器统一管理,自动“注入”,注入即赋值。 而 AOP 使得系统级服务得到了最大复用,且不用再由程序员手工将系统级服务“混杂”到主业务逻辑中

了,而是由 Spring 容器统一完成“织入”。

Spring的优点:

轻量:

​ 1. Spring 框架使用的 jar 都比较小,一般在 1M 以下或者几百 kb。Spring 核心功能的所需的 jar 总共在 3M 左右。

​ 2. Spring 框架运行占用的资源少,运行效率高。

针对接口编程,解耦合:

​ 1. Spring 提供了 Ioc 控制反转,由容器管理对象,不需要程序员关心对象的依赖关系。

​ 2. 原来在程序代码中的对象创建方式,现在由容器完成。实现对象之间的依赖关系解耦合。

使用spring需要的maven依赖:

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.2.5.RELEASE</version>
</dependency>

IoC控制反转

控制反转(IoC,Inversion of Control),是一个概念,是一种思想。指将传统上由程序代码直接操控的对象调用权交给容器,通过容器来实现对象的装配和管

理。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。通过容器实现对象的创建,属性赋值,依赖的管理。

IoC 是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式是依赖注入(DI)。应用广泛。

什么是依赖?

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

DI(依赖注入)

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

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

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

Spring 容器是一个超级大工厂,负责创建、管理所有的 Java 对象,这些 Java 对象被称为 Bean。Spring 容器管理着容器中 Bean 之间的依赖关系,Spring 使

用“依赖注入”的方式来管理 Bean 之间的依赖关系。使用 IoC 实现对象之间的解耦和。

基于XML的DI

通过spring的配置文件实现

注入的分类

bean 实例在调用无参构造器创建对象后,就要对 bean 对象的属性进行初始化。初始化是由容器自动完成的,称为注入。

根据注入方式的不同,常用的有两类:set 注入、构造注入

set注入

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

spring配置文件applicationContext.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">

    <!--
        set注入(设值注入):
        1). 简单类型的注入
            String类型和基本数据类型(String和基本数据类型都算是简单类型)的注入
            类中提供setXxx()方法,会自动调用对应属性的setXxx()方法
        2).引用类型的注入
            使用property标签中的ref属性指定引用类型的id

        tips: set注入看的是有没有setXxx()方法. 即使没有对应的属性,只要右对应的setXxx()方法,也可以执行.

    -->
    <bean id="student" class="cn.tedu.test01.service.impl.Student">
        <!-- 简单类型的注入: name指定类中的属性名,value指定类中属性的值-->
        <property name="name" value="张三"/>
        <property name="age" value="18"/>

        <!-- 引用类型的注入: name指定类中的属性名,ref指定属性的值(引用类型的对象,直接指定对应bean的id) -->
        <property name="school" ref="school"/>

    </bean>
</beans>
构造注入

构造注入是指,在构造调用者实例的同时,完成被调用者的实例化。即,使用构造器设置依赖关系。

spring配置文件applicationContext.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">

    <!-- id属性设置要创建的对象名,class属性设置要创建对象的类的全限定名 -->

    <!-- 默认调用的是无参构造创建的对象 -->
    <bean id="someService" class="cn.tedu.test01.service.impl.SomeServiceImpl"></bean>
    <bean id="myDate" class="java.util.Date"></bean>

    <!-- 使用类中的含参构造创建对象  (构造注入)
         <constructor-arg>: name属性:指定含参构造的形参名,
         参数的类型是简单类型的就是用value指定参数的值,
         参数类型是引用类型就用ref指定对象bean中的id

     -->
    <bean id="student01" class="cn.tedu.test01.service.impl.Student">
        <constructor-arg name="name" value="王五"/>
        <constructor-arg name="age" value="30"/>
        <constructor-arg name="school" ref="school"/>
    </bean>
</beans>
自动注入

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

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

​ byName:根据名称自动注入

​ byType: 根据类型自动注入

<?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">

	<!-- 引用类型的自动注入 (byName的方式)
         自动注入的前提: 需要类中的属性名与bran中的id名保持一致,且数据类型一致
    -->
    <bean id="student" class="cn.tedu.test01.service.impl.Student" autowire="byName">
        <property name="name" value="赵云"/>
        <property name="age" value="21"/>

        <!-- 在<bean>标签中加入autowire="byName", 符合条件就会自动主动引用类型
             不需要手动再自己添加注入-->
        <!-- <property name="school" ref="mySchool"/>-->
    </bean>


    <bean id="school" class="cn.tedu.test01.service.School">
        <property name="name" value="深圳达内"/>
        <property name="address" value="深圳"/>
    </bean>
</beans>

基于注解的 DI (重点)

对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。

需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。

tips: 用SpringBoot整合后, 不需要再spring配置文件中配置组件扫描器. 因为在启动类的@SpringBootAppcation注解中已经扫描了.

定义Bean的注解(创建对象)
@Component

需要在类上使用注解@Component,该注解的 value 属性用于指定该 bean 的 id 值(对象名)。可以不写,默认是首字母小写的类名.

另外,Spring 还提供了 3 个创建对象的注解,功能和用法@Component是一样,只是适用的地方不同:

​ ➢ @Repository 用于对 DAO 实现类进行注解

​ ➢ @Service 用于对 Service 实现类进行注解

​ ➢ @Controller 用于对 Controller 实现类进行注解

下面用@Component举例:

import org.springframework.stereotype.Component;

@Component
public class Cat {
    private String name;
    private Integer age;
}
赋值的注解
@Value (简单类型的赋值)
@Component
public class Cat {

    @Value("咖啡猫")
    private String name;
    @Value("2")
    private Integer age;
}
@Autowired(引用类型自动注入)

@Autowired注解默认是byType,从容器中找到同源关系的对象,进行赋值.

如果要使用byName的方式,需要使用@Qualifier指定对象的名称,使用这个名字的对象,赋值给引用类型

@Component
public class Student {

    private String name;
    private Integer age;

    @Autowired
    private School school;
}

使用@Qualifier指定要匹配的对象名。

@Component
public class Student {

    private String name;
    private Integer age;

    @Autowired
    @Qualifier(value = "xuexiao")
    private School school;
}

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

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

@Resource

@resource注解是JDK提供的。@Resource 注解既可以按名称匹配Bean,也可以按类型匹配 Bean,默认是按名称注入

使用该注解,要求 JDK 必须是 6 及以上版本。@Resource 可在属性上,也可在 set 方法上。

@Component
public class Student {

    private String name;
    private Integer age;

	@resource
    private School school;
}
注解和XML两种方式的对比

注解优缺点是:

  • 方便
  • 直观
  • 高效(代码少,没有配置文件的书写那么复杂)。
  • 其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。

XML 方式优缺点是:

  • 配置和代码是分离的
  • 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。
  • xml 的缺点是:编写麻烦,效率低,大型项目过于复杂。
原文地址:https://www.cnblogs.com/hxgoto/p/15398132.html