spring快速复习(上)

全文来自于https://itbaima.net/document

Spring

基于xml的快速配置

  • 文件结构
    在这里插入图片描述

  • xml

xml 中扫描JavaBean 并配置到容器中

<?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-->
    <bean name="ArtStudent" class="org.example.bean.ArtStudent"/>
</beans>
  • JavaBean

JavaBean 中仅仅定义属性和方法 并不赋值

public class ArtStudent extends Student{

    public void art(){
        System.out.println("我爱画画");
    }
}
  • App

在App界面加载配置文件(new ClassPathXmlApplicationContext("spring.xml")),并进行操作

public class App {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        ArtStudent artStudent = (ArtStudent) context.getBean("ArtStudent");       
    }
}

bean的几种创建方式

//        通过接口获取
        ArtStudent artStudent = (ArtStudent) context.getBean("ArtStudent");
        artStudent.art();
//        通过类获取
        ArtStudent artStudent1 = context.getBean(ArtStudent.class);
        artStudent1.art();
//        通过bean name 获取
        ArtStudent artStudent2 = context.getBean("ArtStudent", ArtStudent.class);
        artStudent2.art();
    }

单例和多例

配置

   <!--    单例-->
       <bean name="ArtStudent" class="org.example.bean.ArtStudent" scope="singleton"/>
   <!--    多例-->
       <bean name="ArtStudent" class="org.example.bean.ArtStudent" scope="prototype"/>
<!--懒加载 到调用的时候才加载-->
       <bean name="ArtStudent" class="org.example.bean.ArtStudent" lazy-init="true"/>

区别

  • 单例:在容器中只有一个实例,每次获取的都是同一个实例
  • 多例:每次获取的都是一个新的实例
  • 默认是单例
  • 当Bean的作用域为单例模式时,那么它会在一开始(容器加载配置时)就被创建,我们之后拿到的都是这个对象。而处于多例模式下,只有在获取时才会被创建,也就是说,单例模式下,Bean会被IoC容器存储,只要容器没有被销毁,那么此对象将一直存在,而原型模式才是相当于在要用的时候直接new了一个对象,并不会被保存。

依赖注入

什么是依赖注入

依赖注入

  • 依赖注入(Dependency Injection, DI)是一种设计模式,也是Spring框架的核心概念之一。
  • 比如现在有一个教师接口:
public interface Teacher {
    void teach();
}
  • 具体的实现有两个:
public class ArtTeacher implements Teacher{
    @Override
    public void teach() {
        System.out.println("我是美术老师,我教你画画!");
    }
}
public class ProgramTeacher implements Teacher{
    @Override
    public void teach() {
        System.out.println("我是编程老师,我教你学Golang!");
    }
}
  • 我们的学生一开始有一个老师教他,比如美术老师:
public class Student {
    private Teacher teacher = new ArtTeacher();   
  	//在以前,如果我们需要制定哪个老师教我们,直接new创建对应的对象就可以了
    public void study(){
        teacher.teach();
    }
}
  • 传统修改
    • 类内部new对象
public class Student {
    private Teacher teacher = new ProgramTeacher();
  	...
  • 通过依赖注入修改变量
    • 需要提供setter 或者构造器
    • 不再需要类内部定义变量
    • 直接改xml文件即可
<bean name="teacher" class="com.test.bean.ProgramTeacher"/>
<bean name="student" class="com.test.bean.Student">
    <property name="teacher" ref="teacher"/>
</bean>
  • 依赖注入注入基础类型
<bean name="student" class="com.test.bean.Student">
    <property name="name" value="卢本伟"/>
</bean>

依赖注入的要求

如果我们需要用依赖注入 要么提供setter方法 要么提供构造器

1. setter

我们还需要修改一下Student类,依赖注入要求对应的属性必须有一个set方法:

public class Student {
    private Teacher teacher;
  	//要使用依赖注入,我们必须提供一个set方法(无论成员变量的访问权限是什么)命名规则依然是驼峰命名法
    public void setTeacher(Teacher teacher) {
        this.teacher = teacher;
    }
2. 指定构造器

当我们移除了无参构造器以后 我们需要在xml中指定构造器

  • 目标注入类
public class Student {
    private final Teacher teacher;   //构造方法中完成,所以说是一个final变量

    public Student(Teacher teacher){   //Teacher属性是在构造方法中完成的初始化
        this.teacher = teacher;
    }
  	...
  • xml
<bean name="teacher" class="com.test.bean.ArtTeacher"/>
<bean name="student" class="com.test.bean.Student">
    <constructor-arg name="teacher" ref="teacher"/>
</bean>
指定构造器的方式
public class Student {
    private final String name;
    public Student(String name){
        System.out.println("我是一号构造方法");
        this.name = name;
    }

    public Student(int age){
        System.out.println("我是二号构造方法");
        this.name = String.valueOf(age);
    }
}
  • 给标签添加类型:
<constructor-arg value="1" type="int"/>
  • 指定为对应的参数名称:
<constructor-arg value="1" name="age"/>

集合这些的依赖注入

  • 集合类型:
public class Student {
    private List<String> list;

    public void setList(List<String> list) {
        this.list = list;
    }
}
  • 对于这种集合类型,有着特殊的支持:
<bean name="student" class="com.test.bean.Student">
  	<!--  对于集合类型,我们可以直接使用标签编辑集合的默认值  -->
    <property name="list">
        <list>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </list>
    </property>
</bean>

ListMapSet这类常用集合类包括数组在内,都是支持这样编写的,比如Map类型,我们也可以使用entry来注入:

<bean name="student" class="com.test.bean.Student">
    <property name="map">
        <map>
            <entry key="语文" value="100.0"/>
            <entry key="数学" value="80.0"/>
            <entry key="英语" value="92.5"/>
        </map>
    </property>
</bean>

bean的生命周期

bean开启生命周期

  • xml 配置init-method 和 destroy-method
  • 在对应的bean中添加对应的方法(init 和 destroy,名字只要能对应xml上的配置就行)
    <bean name="ArtStudent" class="org.example.bean.ArtStudent" init-method="init" destroy-method="des"/>
public class ArtStudent extends Student{
    public void init(){
        System.out.println("初始化");
    }
    public void des(){
        System.out.println("销毁");
    }
}

单例和多例的生命周期

  • 单例的创建开始
  • 关闭容器的时候结束
//当容器创建时,默认情况下Bean都是单例的,那么都会在一开始就加载好,对象构造完成后,会执行init-method
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("test.xml");
//我们可以调用close方法关闭容器,此时容器内存放的Bean也会被一起销毁,会执行destroy-method
context.close();
  • 多例调用时才会创建对象,销毁时不会调用destroy-method

工厂bean 和继承bean(了解)

工厂模式和工厂Bean

  • 目标bean
public class Student {
    Student() {
        System.out.println("我被构造了");
    }
}
  • 工厂bean
public class StudentFactory {
    public static Student getStudent(){
      	System.out.println("欢迎光临电子厂");
        return new Student();
    }
}
  • 工厂bean的配置
<bean class="com.test.bean.StudentFactory" factory-method="getStudent"/>
  • 工厂bean的返回值和使用
    • 工厂bean的返回值是目标bean
    • 调用的时候就是对目标bean 进行了一些前置操作
Student bean = (Student) context.getBean("studentFactory");
// 欢迎光临电子厂 工厂bean加的
// 我被构造了    目标bean自身的

bean的继承(parent)

  • 几个bean之间有共同的属性,可以使用继承的方式(继承不一定需要开abstract
  • 如果设置成abstract,那么这个bean就不能被实例化
<bean name="student" class="com.test.bean.Student" abstract="true">
    <property name="name" value="卢本伟"/>
<!--    因为开了abstract 所以不能直接实例化 也可以不写abstrac-->
</bean>
<bean name="artStudent" class="com.test.bean.ArtStudent" parent="student">
<!--   这里可以直接复用上面的属性-->
</bean>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值