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, byType3.@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类型的,默认truerequired=true:示意援用类型赋值失败,程序报错,并终止执行required=false:援用类型如果赋值失败, 程序失常执行,援用类型是null#### **1.5.6 JDK注解@Resource主动注入**1.@Resource: 来自jdk中的注解,spring框架提供了对这个注解的性能反对,能够应用它给援用类型赋值2.应用的也是主动注入原理,反对byName,byType默认是byName3.应用地位:在属性定义的下面,无需set办法,举荐应用在set办法的下面4.默认是byName:先应用byName主动注入,如果byName赋值失败,再应用byType5.@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;