Spring~带你初步理解Spring(Bean容器、IOC、DI) 知道Spring框架配置使用流程

69 阅读7分钟

怎么理解我们的Spring


  • 理解Spring主要理解Core Container核心容器的三个核心
  1. Bean容器: 是提供管理Java对象的容器

  2. IOC : BeanFactory为IOC提供了完整的服务支持 简单来说, BeanFactory 就是一个管理 Bean容器所有对象的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。所以IOC是在在开发过程中 实例的创建不由调用者管理 , 而是由Spring创建并管理, Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IOC 思想。

  3. Spring : 一个免费开源的轻量级的方便于企业应用开发的一个框架, 具有控制反转(IOC)和面向切面编程(AOP)等特性, 支持事务的处理和其他框架的整合

  4. 使用set注入, 使程序的主动性由主动变为被动, 由原先的主动new 到set的被动接收, 系统的耦合性大大降低, 可以专注于业务的实现, 这就是控制反转IOC的部分原型,

  5. IOC控制对象的反转是对于程序员而言反转了, 也就是不由程序员直接new, 而是让第三方传入, 对于我们程序员而言是被动接收

  6. 控制反转是一种编程思想, DI依赖注入是IOC实现的一种, 在没有IOC的时候, 我们使用面向对象编程, 所有对象的创建和对象之间的关系都是由程序员自己控制, 反转后就交给第三方set给我们程序员,

  7. 第三方包括xml配置文件或者注释, 通过这些第三方产生特定的对象, 并通过依赖注入完善对象, 这个过程也叫IOC控制反转, 所以spring中实现控制反转的是IOC编程思想, 实现依赖注入的是DI

  8. 当我们想要实现不同的操作, 只需要在配置文件中修改即可, 不用去动程序, 总之一句话:对象由spring去创建, 管理,装配, 这就是ioc ,

  9. DI : DI的含义是依赖的注入 其实还是给Bean容器中所有的对象提供服务支持, 本质就是给bean对象注入依赖属性 让每一个对象更加完整 更加有意义.

  10. IOC创建对象的方式: property走的无惨构造, 采用set传入 这是默认!

  11. 可以通过有参构造: 1. 下标构造constructor + index 建议使用 2. 类型构造 constructor + type 3. constructor + “参数名” 直接通过参数名

  12. 必须知道, 只要我们在配置文件中配置了bean 无论我们使用不使用, 他直接都帮我们实例化好了, 也就是无论我们是否getBean()他都已经创建好所有的bean了, 并且创建的只有一个, 即使我们在代码中get相同的bean俩次, 但是获得的是一个

使用依赖注入有俩种方式:

  1. 属性setter注入: 指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI
  1. 构造方法注入: 指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖

bean元素常用属性


  1. 需要让属性有 public 权限或者 setter 有 public 权限

  2. 基本数据类型 + String 用 value,其他引用类型用 ref

  3. 如果要使用集合,有 map、list、set 等直接使用

| id | 是一个 Bean 的唯一标识符,Spring 容器对 Bean 的配置和管理都通过该属性完成

| name | Spring 容器同样可以通过此属性对容器中的 Bean 进行配置和管理,name 属性中可以为 Bean 指定多个名称,每个名称之间用逗号或分号隔开

| class | 该属性指定了 Bean 的具体实现类,它必须是一个完整的类名,使用类的全限定名

| scope | 用于设定 Bean 实例的作用域,其属性值有 singleton(单例)、prototype(原型)、request、session 和 global Session。其默认值是 singleton

| constructor-arg | 元素的子元素,可以使用此元素传入构造参数进行实例化。该元素的 index 属性指定构造参数的序号(从 0 开始),type 属性指定构造参数的类型

| property | 元素的子元素,用于调用 Bean 实例中的 Set 方法完成属性赋值,从而完成依赖注入。该元素的 name 属性指定 Bean 实例中的相应属性名

| ref | 和 等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用

| value | 和 等元素的子元素,用于直接指定一个常量值

| list | 用于封装 List 或数组类型的依赖注入

| set | 用于封装 Set 类型属性的依赖注入

| map | 用于封装 Map 类型属性的依赖注入

| entry | 元素的子元素,用于设置一个键值对。其 key 属性指定字符串类型的键值,ref 或 value 子元素指定其值

代码演示

  • Person类

package Listen;

/**

  • Created with IntelliJ IDEA.

  • Description: If you don't work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-10

  • Time: 20:54

*/

public class Person {

private String name;

private int age;

public Person() {

}

public Person(String name, int age) {

this.name = name;

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public String toString() {

return "Person{" +

"name='" + name + ''' +

", age=" + age +

'}';

}

}

  • Teacher类

package Listen;

/**

  • Created with IntelliJ IDEA.

  • Description: If you don't work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-11

  • Time: 15:25

*/

public class Teacher {

private Person person;

private String teacherId;

public Teacher() {

}

public Teacher(Person person, String teacherId) {

this.person = person;

this.teacherId = teacherId;

}

public Person getPerson() {

return person;

}

public void setPerson(Person person) {

this.person = person;

}

public String getTeacherId() {

return teacherId;

}

public void setTeacherId(String teacherId) {

this.teacherId = teacherId;

}

@Override

public String toString() {

return "Teacher{" +

"person=" + person +

", teacherId='" + teacherId + ''' +

'}';

}

}

  • School类

package Listen;

import java.util.List;

/**

  • Created with IntelliJ IDEA.

  • Description: If you don't work hard, you will a loser.

  • User: Listen-Y.

  • Date: 2020-08-11

  • Time: 15:26

*/

public class School {

private List teachers;

private String schoolName;

public School() {

}

public School(List teachers, String schoolName) {

this.teachers = teachers;

this.schoolName = schoolName;

}

public List getTeachers() {

return teachers;

}

public void setTeachers(List teachers) {

this.teachers = teachers;

}

public String getSchoolName() {

return schoolName;

}

public void setSchoolName(String schoolName) {

this.schoolName = schoolName;

}

@Override

public String toString() {

return "School{" +

"teachers=" + teachers +

", schoolName='" + schoolName + ''' +

'}';

}

}

  • 配置文件中的配置项的每个bean对象

<beans xmlns="www.springframework.org/schema/bean…"

xmlns:xsi="www.w3.org/2001/XMLSch…"

xsi:schemaLocation="www.springframework.org/schema/bean…

www.springframework.org/schema/bean…

  • 根据容器获取bean并且使用bean对象

import Listen.Person;

import Listen.School;

import Listen.Teacher;

import org.springframework.context.ApplicationContext;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Main {

public static void main(String[] args) {

//加载配置文件

//Spring开启容器的方式就是应用上下文(可以配置管理bean对象 及其他工作)

//根据classpath路径 指定一个配置文件

//根据配置文件完成配置工作(如bean的实例化)

ApplicationContext context = new

ClassPathXmlApplicationContext("applications.xml");

//通过bean的名称获取bean对象

String love = (String)context.getBean("love");

System.out.println(love);

//通过类型获得bean对象 如果该类型有多个对象 就会报错 只支持一个该类型的对象 返回的是一个泛型对象可以忽略强转

String love1 = context.getBean(String.class);

System.out.println(love1);

System.out.println("====测试自定义类====");

Person person = (Person) context.getBean("person");

System.out.println(person);

Person person2 = (Person)context.getBean("person2");

System.out.println(person2);

Person person3 = (Person)context.getBean("person3");

System.out.println(person3);

Teacher teacher1 = (Teacher)context.getBean("teacher1");

System.out.println(teacher1);

Teacher teacher2 = (Teacher)context.getBean("teacher2");

System.out.println(teacher2);

Teacher teacher3 = (Teacher)context.getBean("teacher3");

System.out.println(teacher3);

School school = (School)context.getBean("school");

System.out.println(school);

}

}

  • 运行结果

16:15:44.050 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@6504e3b2

16:15:44.337 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 8 bean definitions from class path resource [applications.xml]

16:15:44.403 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'love'

16:15:44.495 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person'

16:15:44.530 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person2'

16:15:44.533 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person3'

16:15:44.534 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'teacher1'

16:15:44.544 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'teacher2'

16:15:44.547 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'teacher3'

16:15:44.548 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'school'

love

love

====测试自定义类====

Person{name='listen', age=21}

Person{name='frank', age=20}

Person{name='jake', age=22}

Teacher{person=Person{name='listen', age=21}, teacherId='5201314'}

Teacher{person=Person{name='frank', age=20}, teacherId='7654321'}

Teacher{person=Person{name='jake', age=22}, teacherId='1234567'}

School{teachers=[Teacher{person=Person{name='listen', age=21}, teacherId='5201314'}, Teacher{person=Person{name='frank', age=20}, teacherId='7654321'}, Teacher{person=Person{name='jake', age=22}, teacherId='1234567'}], schoolName='HappySchool'}

Process finished with exit code 0

常见所有类型的注入


<beans xmlns="www.springframework.org/schema/bean…"

xmlns:xsi="www.w3.org/2001/XMLSch…"

xsi:schemaLocation="www.springframework.org/schema/bean…

www.springframework.org/schema/bean…

西游记

水浒传

三国演义

听歌

看电影

跑步

LOL

CF

QQ

XXX

YYY