Spring从基础开始到熟悉的知识笔记(idea版)--持续更新

Spring(idea版)

简介

全家桶springspring bootspringmvcspring cloud

初衷:解决企业开发的难度,减轻对项目模块之间的管理,类和类之间的管理,帮助开发人员创建对象,管理对象之间的关系。

核心技术ioc, aop 能实现模块之间,类之间的解耦合

依赖:class A中使用class B的属性或方法,叫做class A依赖class B

IOC

(Inversion of control)控制反转:是一个理论,概念,思想。

把对象的创建,赋值,管理工作都交给代码之外的容器实现,也就是对象的创建是有其他外部资源完成。

控制:创建对象,对象的属性赋值,对象之间的关系管理。

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

正转:由开发人员在代码中,使用new 构造方法创建对象,开发人员主动管理对象

public static void main(String args[]){
  student student = new Student(); //在代码中,创建对象 --正转
}

容器:是一个服务器软件,一个框架(spring)

为什么要使用ioc:目的就是减少对代码的改动,也能实现不同的功能,实现解耦合

java 中创建对象有哪些方式:

  1. 构造方法
  2. 反射
  3. 序列化
  4. 克隆
  5. ioc :容器创建对象
  6. 动态代理

ioc 的体现:

servlet :

  1. 创建类继承HttpServlet
  2. web.xml注册servlet,使用<servlet-name> myservlet </servlet-name>
  3. 没有创建servlet对象,没有new出来,所以servlettomcat创建的。tomcat作为容器:里面存放着servlet对象,listener filter

IOC 的技术实现:

DI是ioc的技术实现,DI叫做依赖注入:只需要在程序中提供要使用的对象就可以了,至于这个对象如何创建,赋值,查找,都由容器内部实现。

spring是使用了di实现了ioc的功能,spring底层创建对象,使用的是反射机制。

创建项目配置spring:

  1. 创建maven项目

  2. 加入maven的依赖

    1. spring的依赖,版本5.2.5版本
    2. junit依赖
  3. 创建类(接口和他的实现类)要自己写

    和没有使用框架一样,就是普通的类

  4. 创建spring需要使用的配置文件

    声明类的信息,这些类由spring创建和管理

    通过spring的语法,完成属性的赋值

  5. 测试spring创建的对象

引入maven依赖pom.xml

<!--  spring的依赖  -->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>5.2.5.RELEASE</version>
    </dependency>

创建spring配置文件

beans.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">
<!--
  告诉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="org.example.service.impl.SomeServiceImpl" />
</beans>
<!--
  spring的配置文件
  1.beans:是跟标签,spring把java对象称为bean
  2.spring-beans.xsd 是约束文件,和mybatis指定dtd是一样的
-->

创建容器对象ApplicationContext

在测试类中创建ApplicationContext对象

// 测试spring的使用
    @Test
    public void test02() {
        // 使用spring容器创建的对象
        // 1.指定spring配置文件的名称
        String config = "beans.xml";
        // 2.创建表示spring容器的对象,ApplicationContext
        // ApplicationContext就是表示Spring容器,通过容器获取对象了
        // ClassPathXmlApplicationContext表示从类路径中加载spring的配置文件
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 从容器中获取某个对象,你要调用对象的方法
        // getBean("配置文件中bean的id值")
        SomeService service = (SomeService) ac.getBean("someService");

        // 使用spring创建好的对象
        service.doSome();
    }

ApplicationContext ac = new ClassPathXmlApplicationContext(config) 读取spring的配置文件

ac.getBean("someService") 使用spring中配置的某个类并创建它的对象

service.doSome() 使用对象

spring创建对象的时机

spring默认创建对象的时间:在创建spring的容器时,会创建配置文件中的所有的对象

获取容器中对象信息的API举例

获取容器中定义对象的数量

@Test
    public void test03() {
        String config = "beans.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 使用spring提供的方法,获取容器中定义对象的数量
        int nums = ac.getBeanDefinitionCount();
        System.out.println("在容器中定义的对象的数量是:" + nums);
    }

获取容器中对象的每个对象的名称

@Test
    public void test03() {
        String config = "beans.xml";
        ApplicationContext ac = new ClassPathXmlApplicationContext(config);
        // 容器中每个定义的对象的名称
        String names[] = ac.getBeanDefinitionNames();
        for(String name:names) {
            System.out.println(name);
        }
    }

spring创建非自定义对象

spring能创建一个非自定义的对象吗?创建一个已存在的某个类的对象。是可以的

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

设值注入概念

DI:依赖注入,表示创建对象,给属性赋值

DI的实现有两种

  1. 在spring的配置文件中,使用标签和属性完成,叫做基于XML的di实现
  2. 使用spring中的注解,完成赋值,叫做基于注解的id实现

DI的语法分类:

  1. set注入(设置注入):spring调用类的set方法,在set方法可以实现属性的赋值,百分之80都是使用set注入
  2. 构造注入,spring调用类的有参构造方法,创建对象,在构造方法中完成赋值

简单类型的set注入

set注入(设置注入):spring调用类的set方法,你可以在set方法中完成赋值

<bean id="xx" class="yyyy">
  <property name="属性名字" value="此属性的值" />
  一个property只能给一个属性赋值
  <property ... />
</bean>

它会去调用类的set方法去帮你赋值

<bean id="myPerson" class="org.example.set.Person" >
      <property name="age" value="10" />
      <property name="name" value="李四" />
</bean>

类中set方法设置输出

在这里插入图片描述

测试类输出

在这里插入图片描述

设值注入的注意事项

需要有set方法,没有set方法会报错

Bean property 'xxx' is not writable or has an invalid setter method

引用类型的设值注入(原始方法)

引用类型的设值注入跟简单类型的设值注入大同小异。

格式:引用类型的set注入:spring调用类的set方法

<bean id="xx" class="yyyy">
  <property name="属性名字" ref="bean的id(对象的名称)" />
</bean>

举例:

School类

在这里插入图片描述

Person类(其中有个引用类型school)

在这里插入图片描述

xml配置

在这里插入图片描述

测试方法测试spring容器

在这里插入图片描述

构造注入

因为spring默认调用的无参构造函数,所以如果要使用构造函数赋值,那么就要在xml文件中增加配置,让spring调用有参构造方法去赋值。

spring调用类的有参数构造方法,在创建对象的同时,在构造方法中给属性赋值

构造注入使用<constructor-arg>标签
<constructor-arg>标签属性:
name:表示构造方法的形参名
index:表示构造方法的参数的位置,参数从左往右位置是0,1,2的顺序
value:构造方法的形参类型是简单类型的,使用value,
ref:构造方法的形参类型是引用类型的,使用ref

例:

Person类中增加有参构造函数:

/**
 * 有参构造方法
 * @param age
 * @param name
 * @param school
 */
public Person(int age, String name, School school) {
    this.age = age;
    this.name = name;
    this.school = school;
    System.out.println("==Person类的有参构造方法==");
}

XML配置文件增加调用有参注入的配置:

<bean id="myPerson" class="org.example.set.Person" >
      <constructor-arg name="age" value="23" />
      <constructor-arg name="name" value="张三" />
      <constructor-arg name="school" ref="mySchool" />
</bean>
<!-- 声明School对象 -->
<bean id="mySchool" class="org.example.set.School" >
      <property name="name" value="大连海事大学" />
      <property name="address" value="大连市甘井子区凌海路1号" />
</bean>

测试类输出:

在这里插入图片描述

构造注入创建文件对象

XML文件配置:

<bean id="myFile" class="java.io.File" >
      <constructor-arg name="parent" value="D:\Iprogram\java_program\spring_01\hello_spring" />
      <constructor-arg name="child" value="pom.xml" />
</bean>

增加测试类方法:

@Test
public void Test04() {
    String config = "set/setBeans.xml";
    ApplicationContext ac2 = new ClassPathXmlApplicationContext(config);

    // 从容器中拿到File对象
    File fl = (File) ac2.getBean("myFile");
    System.out.println(fl.getName());
}

测试结果

在这里插入图片描述

自动注入

引用类型的自动注入:spring框架根据某些规则可以给引用类型赋值,不用你再给引用类型赋值了

使用的规则常用的是byNamebyType

byName

byName(按名称注入):Java类中引用类型的属性名和spring容器中(配置文件)的id名称一样,且数据类型是一致的,这样的容器中的bean,spring能够赋值给引用类型

语法:

<bean id="xx" class="yyy" autowire="byName">简单类型属性赋值</bean>

例:

<bean id="myPerson" class="org.example.set.Person" autowire="byName" >
      <property name="age" value="23" />
      <property name="name" value="李四" />
      <!--<property name="school" ref="mySchool" />-->
</bean>
<!-- 声明School对象,这里的id就不能随机设置,而是跟属性名相同 -->
<bean id="school" class="org.example.set.School" >
      <property name="name" value="大连海事大学" />
      <property name="address" value="大连市甘井子区凌海路1号" />
</bean>

这里的引用类型的配置id就不能随机设置,而是跟类中引用类型的属性名相同

byType

byType(按类型注入):java类中引用类型的数据类型和spring容器中(配置文件)的class属性是同源关系的,这样的bean能够赋值给引用类型

同源就是一类的意思:

  1. java类中引用类型的数据类型和bean的class的值是一样的
  2. java类中引用类型的数据类型和bean的class的值是父子类关系的。
  3. java类中引用类型的数据类型和bean的class的值接口和实现类关系的

注意:在byType中,在xml配置文件中声明bean只能由一个符合条件的,多余一个会报错

语法:

<bean id="xx" class="yyy" autowire="byType">简单类型属性赋值</bean>

例:

<bean id="myPerson" class="org.example.set.Person" autowire="byType" >
      <property name="age" value="23" />
      <property name="name" value="李四" />
      <!--<property name="school" ref="mySchool" />-->
</bean>
<!-- 声明School对象,这里的org.example.set.School和Person中school的类型是一致的,所以spring就使用了mySchool -->
<bean id="mySchool" class="org.example.set.School" >
      <property name="name" value="大连海事大学" />
      <property name="address" value="大连市甘井子区凌海路1号" />
</bean>

例2:如果DalianHaishi类为School的子类

<bean id="myPerson" class="org.example.set.Person" autowire="byType" >
      <property name="age" value="23" />
      <property name="name" value="李四" />
      <!--<property name="school" ref="mySchool" />-->
</bean>
<!-- 声明School对象,这里的org.example.set.DalianHaishi为School的子类,所以spring就使用了dalianSchool -->
<bean id="dalianSchool" class="org.example.set.DalianHaishi" >
      <property name="name" value="大连海事大学" />
      <property name="address" value="大连市甘井子区凌海路1号" />
</bean>

例3:现有个Dao接口,DaoImpl实现类,Person里面有个属性为Dao接口类型的

<!-- 实现类 -->
<bean id="oracleDao" class="org.example.set.OracleDaoImpl" autowire="byType" ></bean>
<!-- 接口 -->
<bean id="userService" class="org.example.set.oracleDao" >
      <property name="dao" ref="oracleDao" />
</bean>

多配置文件

优势:

  1. 每个文件的大小比一个文件要小很多,效率高
  2. 避免多人竞争带来的冲突

分配方式:

  1. 按功能模块,一个模块一个配置文件
  2. 按类的功能,数据库相关的配置一个文件配置文件,做事务的功能一个配置文件,做service功能的一个配置文件

spring主配置文件:包含其他的配置文件,一般是不定义对象的

语法:

<import resource="其他配置文件的路径" />

关键字:“classpath”:表示类路径(class文件所在的目录),在spring的配置文件中要指定其他文件的路径,需要使用classpath,告诉spring到哪去加载读取文件

例:

spring-student.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">
       <bean id="mySchool" class="org.example.student.Student">
           <property name="age" value="24" />
           <property name="name" value="小王" />
       </bean>
</beans>

spring-school.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">
    <bean id="mySchool" class="org.example.school.School">
        <property name="managerName" value="王刚" />
        <property name="name" value="大连海事大学" />
    </bean>
</beans>

spring-files.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">
    <import resource="classpath:school/spring-school.xml" />
    <import resource="classpath:student/spring-student.xml" />
</beans>

注解的使用※

通过注解完成java对象的创建,属性赋值

使用注解的步骤:

  1. 加入maven的依赖,spring-context,在你加入spring-context的同时,间接加入spring-aop的依赖,使用注解必须使用spring-aop的依赖
  2. 在类中加入spring的注解
  3. 在spring的配置文件中,加入一个组件扫描器的标签,说明注解在你项目的位置

声明组件扫描器(component-scan)

<context:component-scan base-package="" />

base-package:指定注解在你项目中的包名。

component-scan:工作方式:spring会扫描遍历base-package指定的包,把包中和子包中的所有类,找到类中的注解,按照注解的功能创建对象,或给属性赋值。

在加入了component-scan标签,配置文件的变化:

  1. 加入一个新的约束文件spring-context.xsd
  2. 给这个新的约束文件起个命名空间的名称
指定多个包的三种方式:
使用多次组件扫描器,指定不同的包
<context:component-scan base-package="org.example.test.component1" />
<context:component-scan base-package="org.example.test.component2" />
<context:component-scan base-package="org.example.test.component3" />
使用分割符(;或,)分隔多个包名
<context:component-scan base-package="org.example.test.component1;org.example.test.component2;org.example.test.component3" />
指定父包
<context:component-scan base-package="org.example.test" />

学习注解:

  1. @Component:创建对象的,等同于的功能

    属性:value 就是对象的名称,也就是bean的id值

    ​ value的值是唯一的,创建的对象在整个spring容器中就一个

    位置:在类的上面

    @Component(value = "myStudent") 等同于
    <bean id="myStudent" class="cn.iceseasyh.Student">
    

    如果value不指定名称,则默认使用的是类名称(首字母小写)

  2. @Respotory

  3. @Service

  4. @Controller

  5. @Value:给简单类型的属性赋值

    属性:value是String类型的,表示简单类型的属性值。

    位置:

    1. 在属性定义的上面,无需set方法,推荐使用
    @Value(value="张飞")
    private String name;
    @Value(value="中国")
    private String address;
    
    1. 在set方法的上面
    @Value(value="张飞")
    public void setName(String name) {
        this.name = name;
    }
    
  6. @Autowired:给引用类型赋值,使用的是自动注入原理,支持byName,byType,它默认使用byType自动注入

    如果要使用byName方式,需要做的是

    1. 在属性上面加入@Autowired
    2. 在属性上面加入@Qualifier(value="bean的id"),表示使用指定名称的bean完成赋值
    @Autowired
    @Qualifier(value = "myDemo")
    private ComponentDemo componentDemo;
    

    位置:

    1. 在属性定义的上面,无需set方法,推荐使用

      @Autowired
      private ComponentDemo componentDemo;
      
    2. 在set方法的上面,不推荐

    @Autowiredrequired属性:是一个boolean类型的,默认true

    required=true:表示引用类型赋值失败,程序报错,并终止执行

    required=false:引用类型如果赋值失败,程序正常执行,引用类型是null

    建议不要使用false,用true可以提前暴露问题,错误。

  7. @Resource:来自于JDK的注解,不是spring提供的,spring提供了对jdk中@Resource注解的支持。Resource注解既可以按名称匹配Bean,也可以按类型匹配Bean,默认是按名称注入。使用该注解,要求JDK必须是6及以上版本的。它自动注入的逻辑是先使用byName,如果byName赋值失败,再使用byType进行赋值

    @Resource
    private ComponentDemo componentDemo;
    

    位置:

    1. 在属性定义的上面,无序set方法,推荐使用
    2. 在set方法的上面

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

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

通过spring的注解完成java对象的创建,属性。代替xml文件

实现步骤:

  1. 加入依赖
  2. 创建类,在类中加入注解
  3. 创建spring的配置文件,声明组件扫描器的标签,指名注解在你的项目中的位置
  4. 使用注解创建对象,创建容器ApplicationContext

多注解项目分层

以下三个注解的使用语法和@Component一样的,都能创建对象,但是这三个注解还有额外的功能。

  1. @Respotory:用在持久层类上面,跟@Component一样是创建对象的,放在dao的实现类上面,表示创建dao对象,dao对象是能访问数据库的
  2. @Service:用在业务层类的上面,跟@Component一样是创建对象的,放在service的实现类上面,创建service对象,service对象是做业务处理的,可以有事务等功能。
  3. @Controller:用在控制器的上面,跟@Component一样是创建对象的,放在控制器(处理器)类的上面,创建控制器对象的,控制器对象能够接收用户提交的参数,显示请求的处理结果。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值