关于java:动力节点Spring框架学习笔记王鹤一IOC控制反转

4次阅读

共计 9499 个字符,预计需要花费 24 分钟才能阅读完成。

Spring 框架学习笔记

官网下载地址

能源节点 spring 材料

视频观看地址

https://www.bilibili.com/vide…

一、IOC 管制反转

1.1 概述

管制反转(IoC,Inversion of Control),是一个概念,是一种思维。指将传统上由程序代码间接操控的对象调用权交给容器,通过容器来实现对象的拆卸和治理。管制反转就是对对象控制权的转移,从程序代码自身反转到了内部容器。通过容器实现对象的创立,属性赋值,依赖的治理

IoC 是一个概念,是一种思维,其实现形式多种多样。以后是依赖注入。利用宽泛

依赖:classA 类中含有 classB 的实例,在 classA 中调用 classB 的办法实现性能,即 classA
对 classB 有依赖。

1.2 IOC 的实现

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

依赖注入 DI 是指程序运行过程中,若须要调用另一个对象帮助时,毋庸在代码中创立
被调用者,而是依赖于内部容器,由内部容器创立后传递给程序。

Spring 的依赖注入对调用者与被调用者简直没有任何要求,齐全反对对象之间依赖关系
的治理。

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

Spring 容器治理着容器中 Bean 之间的依赖关系,Spring 应用“依赖注入”的形式来治理 Bean 之间的依赖关系。应用 IoC 实现对象之间的解耦和。

1.3 对于 bean 标签

bean 标签的配置

<!-- 通知 spring 创建对象
        申明 bean,就是通知 spring 要创立某个类的对象
        id: 对象的自定义名称,惟一值。spring 通过这个名称找到对象
        class: 类的全限定名称(不能是接口,因为 spring 是反射机制创建对象,必须应用类)spring 就实现 SomeService someService = new SomeServiceImpl();
        spring 是把创立好的对象放入到 map 中,spring 框架有一个 map 寄存对象的。springMap.put(id 的值,对象);例如 springMap.put("someService", new SomeServiceImpl());

        一个 bean 标签申明一个对象。-->
    <bean id="someService" class="com.jjh.service.impl.SomeServiceImpl" />
    <bean id="someService1" class="com.jjh.service.impl.SomeServiceImpl" scope="prototype"/>

测试类(1)应用

@Test
    public void test01(){SomeService service  = new SomeServiceImpl();
        service.doSome();}

测试类(2)应用

@Test
    public void test03(){
        String config="beans.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 应用 spring 提供的办法,获取容器中定义的对象的数量
        int nums  = ac.getBeanDefinitionCount();
        System.out.println("容器中定义的对象数量:"+nums);
        // 容器中每个定义的对象的名称
        String names [] = ac.getBeanDefinitionNames();
        for(String name:names){System.out.println(name);
        }
    }

1.4 基于 XML 的 DI

1.4.1 set 注入(重点)

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

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

    <!-- 申明 student 对象
        注入:就是赋值的意思
        简略类型:spring 中规定 java 的根本数据类型和 String 都是简略类型。di: 给属性赋值
        1. set 注入(设值注入):spring 调用类的 set 办法,你能够在 set 办法中实现属性赋值
         1)简略类型的 set 注入
            <bean id="xx" class="yyy">
               <property name="属性名字" value="此属性的值"/>
               一个 property 只能给一个属性赋值
               <property....>
            </bean>
            
         2) 援用类型的 set 注入:spring 调用类的 set 办法
           <bean id="xxx" class="yyy">
              <property name="属性名称" ref="bean 的 id(对象的名称)" />
           </bean>
    -->
    <bean id="myStudent" class="com.jjh.ba02.Student" >
        <property name="name" value="李四" />
        <property name="age" value="26" />
        <!-- 援用类型 -->
        <property name="school" ref="mySchool" /><!--setSchool(mySchool)-->
    </bean>
    
    <!-- 申明 School 对象 -->
    <bean id="mySchool" class="com.jjh.ba02.School">
        <property name="name" value="北京大学"/>
        <property name="address" value="北京的海淀区" />
    </bean>
</beans>

1.4.2 结构注入

结构注入是指,在结构调用者实例的同时,实现被调用者的实例化。即应用结构器设置依赖关系。

<!--
        2. 结构注入:spring 调用类有参数构造方法,在创建对象的同时,在构造方法中给属性赋值。结构注入应用 <constructor-arg> 标签
          <constructor-arg> 标签:一个 <constructor-arg> 示意构造方法一个参数。<constructor-arg> 标签属性:name: 示意构造方法的形参名
             index: 示意构造方法的参数的地位,参数从左往右地位是 0,1,2 的程序
             value:构造方法的形参类型是简略类型的,应用 value
             ref:构造方法的形参类型是援用类型的,应用 ref
    -->
            <!-- 应用 name 属性实现结构注入 -->
            <bean id="myStudent" class="com.jjh.ba03.Student" >
                <constructor-arg name="myage" value="20" />
                <constructor-arg name="mySchool" ref="myXueXiao" />
                <constructor-arg name="myname" value="周良"/>
            </bean>
        
            <!-- 应用 index 属性 -->
            <bean id="myStudent2" class="com.jjh.ba03.Student">
                <constructor-arg index="1" value="22" />
                <constructor-arg index="0" value="李四" />
                <constructor-arg index="2" ref="myXueXiao" />
            </bean>
        
            <!-- 省略 index-->
            <bean id="myStudent3" class="com.jjh.ba03.Student">
                <constructor-arg  value="张强强" />
                <constructor-arg  value="22" />
                <constructor-arg  ref="myXueXiao" />
            </bean>

1.4.3 援用类型主动注入

  • byName(按名称注入)

java 类中援用类型的属性名和 spring 容器中(配置文件)<bean> 的 id 名称一样,且数据类型是统一的,这样的容器中的 bean,spring 可能赋值给援用类型。

<!--
        语法:<bean id="xx" class="yyy" autowire="byName">
            简略类型属性赋值
         </bean>
         -->
         
    <bean id="myStudent" class="com.jjh.ba04.Student" autowire="byName">
        <property name="name" value="李四" />
        <property name="age" value="26" />
        <!-- 援用类型 -->
        <!--<property name="school" ref="mySchool" />-->
    </bean>

    <!-- 申明 School 对象 -->
    <bean id="school" class="com.jjh.ba04.School">
        <property name="name" value="清华大学"/>
        <property name="address" value="北京的海淀区" />
    </bean>
  • byType(按类型注入)

java 类中援用类型的数据类型和 spring 容器中(配置文件)的 class 属性是同源关系的,这样的 bean 可能赋值给援用类型

<!--
        语法:<bean id="xx" class="yyy" autowire="byType">
            简略类型属性赋值
         </bean>

         留神:在 byType 中,在 xml 配置文件中申明 bean 只能有一个符合条件的,多余一个是谬误的
-->
    <!--byType-->
    <bean id="myStudent" class="com.jjh.ba05.Student" autowire="byType">
        <property name="name" value="张飒" />
        <property name="age" value="26" />
        <!-- 援用类型 -->
        <!--<property name="school" ref="mySchool" />-->
    </bean>

    <!-- 申明 School 对象 -->
    <bean id="mySchool" class="com.jjh.ba05.School">
        <property name="name" value="人民大学"/>
        <property name="address" value="北京的海淀区" />
    </bean>

1.4.4 具备关联关系的配置

  • student 类的配置文件

    
            <!--student 模块 bean 申明 -->
        <bean id="myStudent" class="com.jjh.domain.entity.Student" autowire="byType">
            <property name="name" value="张三"/>
            <property name="age" value="23"/>
            <!-- 援用类型数据 -->
        </bean>
  • School 类的配置文件

        <bean id="mySchool" class="com.jjh.domain.entity.School">
            <property name="address" value="松潘"/>
            <property name="name" value="工大"/>
        </bean>
  • total 配置文件

        <!--
             蕴含关系的配置文件:spring-total 示意主配置文件:蕴含其余的配置文件的,主配置文件个别是不定义对象的。语法:<import resource="其余配置文件的门路" />
             关键字:"classpath:" 示意类门路(class 文件所在的目录),在 spring 的配置文件中要指定其余文件的地位,须要应用 classpath,通知 spring 到哪去加载读取文件。-->

    <!– 加载的是文件列表 –>
    <!–
    <import resource=”classpath:ba01/applicationContext01.xml” />
    <import resource=”classpath:ba01/applicationContext02.xml” />
    –>

    <!–
       在蕴含关系的配置文件中,能够通配符(*:示意任意字符)
       留神:主的配置文件名称不能蕴含在通配符的范畴内(不能叫做 spring-total.xml)
    –>
    <!– 导入配置文件 –>
    <import resource=”classpath:ba01/applicationContext*”/>


#### 1.5 基于注解的 DI

* ** 注解配置的束缚文件 **

<?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
       http://www.springframework.or…
       http://www.springframework.or…
       https://www.springframework.o…d”>

< !–spring 创立容器时要扫描的包  @ComponentScan –> 
< context:component-scan base-package=”com.jjh”>
< /context:component-scan >
< /beans >


* ** 实体类 **

@Data
@Component(“myStudent”)
public class Student {
    private String name;
    private int age;
    // 援用类型
    private School school;
    }



* ** 测试类中调用 **

  @Test
    public void demo01(){
        String config = “applicationContext.xml”;
        ApplicationContext app = new ClassPathXmlApplicationContext(config);
        Student myStudent = (Student)app.getBean(“myStudent”);
        System.out.println(myStudent);
    }


**1.5.1 应用注解的步骤 **

1. 退出 maven 的依赖 spring-context,在你退出 spring-context 的同时,间接退出 spring-aop 的依赖。应用注解必须应用 spring-aop 依赖

2. 在类中退出 spring 的注解(多个不同性能的注解)3. 在 spring 的配置文件中,退出一个 component-scan 组件扫描器的标签,阐明注解在你的我的项目中的地位   

< !– 申明组件扫描器(component-scan), 组件就是 java 对象
        base-package:指定注解在你的我的项目中的包名。
        component-scan 工作形式:spring 会扫描遍历 base-package 指定的包,
           把包中和子包中的所有类,找到类中的注解,依照注解的性能创建对象,或给属性赋值。

       退出了 component-scan 标签,配置文件的变动:
        1. 退出一个新的束缚文件 spring-context.xsd
        2. 给这个新的束缚文件起个命名空间的名称
    –>
    <context:component-scan base-package=”com.jjh.ba01″ />


**1.5.2 多注解我的项目分层 **

1. @Component: 创建对象的,等同于 <bean> 的性能

属性:value 就是对象的名称,也就是 bean 的 id 值,value 的值是惟一的,创立的对象在整个 spring 容器中就一个

2. @Repository(用在长久层类的下面): 放在 dao 的实现类下面,示意创立 dao 对象,dao 对象是能拜访数据库的。3. @Service(用在业务层类的下面):放在 service 的实现类下面,创立 service 对象,service 对象是做业务解决,能够有事务等性能的。4. @Controller(用在控制器的下面):放在控制器(处理器)类的下面,创立控制器对象的,控制器对象,可能承受用户提交的参数,显示申请的处理结果

以上三个注解的应用语法和 @Component 一样的。都能创建对象,然而这三个注解还有额定的性能。**1.5.3 简略类型的赋值 **

@Value: 简略类型的属性赋值

属性:value 是 String 类型的,示意简略类型的属性值

应用地位:

1. 在属性定义的下面,无需 set 办法,举荐应用。2. 在 set 办法的下面

** 配置文件 **

<context:component-scan base-package=”com.jjh”/>
    <!– 配置属性的 properties 文件 –>
    <context:property-placeholder location=”classpath:student.properties”/>


**properties 文件 **

name=Dick
age=20
@Component(“myStudent”)
public class Student {

    //@Value(“ 李四 ”)
    @Value(“${myname}”) // 应用属性配置文件中的数据
    private String name;

    @Value(“${myage}”)  // 应用属性配置文件中的数据
    private Integer age;
    }


**1.5.4 援用类型的赋值 **

默认形式

1.@Autowired: spring 框架提供的注解,实现援用类型的赋值

2.spring 中通过注解给援用类型赋值,应用的是主动注入原理,反对 byName, byType

3.@Autowired: 默认应用的是 byType 主动注入

4. 应用地位:* 在属性下面应用
* 在 set 办法下面应用

@Component(“myStudent”)
public class Student {

    @Value(“ 李四 ”)
    private String name;
    @Value(“20”)
    private Integer age;

    @Autowired
    private School school;
    }


通过名称赋值

如果要应用 byName 形式:

在属性下面退出 @Autowired

属性下面退出 @Qualifier(value="bean 的 id"):示意应用指定名称的 bean 实现赋值在

@Component(“myStudent”)
public class Student {

    @Value(“ 李四 ”)
    private String name;
    @Value(“20”)
    private Integer age;

    @Autowired
    @Qualifier(“mySchool”)
    private School school;
    }

#### **1.5.5 Autowired 的 required 属性 **

required : 是一个 boolean 类型的,默认 true
required=true:示意援用类型赋值失败,程序报错,并终止执行
required=false:援用类型如果赋值失败,程序失常执行,援用类型是 null

#### **1.5.6 JDK 注解 @Resource 主动注入 **

1.@Resource: 来自 jdk 中的注解,spring 框架提供了对这个注解的性能反对,能够应用它给援用
类型赋值

2. 应用的也是主动注入原理,反对 byName,byType 默认是 byName

3. 应用地位:在属性定义的下面,无需 set 办法,举荐应用
在 set 办法的下面
4. 默认是 byName:先应用 byName 主动注入,如果 byName 赋值失败,再应用 byType

5.@Resource 只应用 byName 形式,须要减少一个属性 name,name 的值是 bean 的 id(名称)** 指定 name**

**@Component("myStudent")
public class Student {@Value("李四")
    private String name;
    private Integer age;

    // 只应用 byName
    @Resource(name = "mySchool")
    private School school;**

** 默认配置 **

@Component(“myStudent”)
public class Student {

    @Value(“ 李四 ”)
    private String name;
    private Integer age;

    // 只应用 byName
    @Resource
    private School school;

正文完
 0