- 理解Spring主要理解Core Container核心容器的三个核心
-
Bean容器: 是提供管理Java对象的容器
-
IOC : BeanFactory为IOC提供了完整的服务支持 简单来说, BeanFactory 就是一个管理 Bean容器所有对象的工厂,它主要负责初始化各种 Bean,并调用它们的生命周期方法。所以IOC是在在开发过程中 实例的创建不由调用者管理 , 而是由Spring创建并管理, Spring 容器会负责控制程序之间的关系,而不是由程序代码直接控制,因此,控制权由程序代码转移到了 Spring 容器中,控制权发生了反转,这就是 Spring 的 IOC 思想。
-
Spring : 一个免费开源的轻量级的方便于企业应用开发的一个框架, 具有控制反转(IOC)和面向切面编程(AOP)等特性, 支持事务的处理和其他框架的整合
-
使用set注入, 使程序的主动性由主动变为被动, 由原先的主动new 到set的被动接收, 系统的耦合性大大降低, 可以专注于业务的实现, 这就是控制反转IOC的部分原型,
-
IOC控制对象的反转是对于程序员而言反转了, 也就是不由程序员直接new, 而是让第三方传入, 对于我们程序员而言是被动接收
-
控制反转是一种编程思想, DI依赖注入是IOC实现的一种, 在没有IOC的时候, 我们使用面向对象编程, 所有对象的创建和对象之间的关系都是由程序员自己控制, 反转后就交给第三方set给我们程序员,
-
第三方包括xml配置文件或者注释, 通过这些第三方产生特定的对象, 并通过依赖注入完善对象, 这个过程也叫IOC控制反转, 所以spring中实现控制反转的是IOC编程思想, 实现依赖注入的是DI
-
当我们想要实现不同的操作, 只需要在配置文件中修改即可, 不用去动程序, 总之一句话:对象由spring去创建, 管理,装配, 这就是ioc ,
-
DI : DI的含义是依赖的注入 其实还是给Bean容器中所有的对象提供服务支持, 本质就是给bean对象注入依赖属性 让每一个对象更加完整 更加有意义.
-
IOC创建对象的方式: property走的无惨构造, 采用set传入 这是默认!
-
可以通过有参构造: 1. 下标构造constructor + index 建议使用 2. 类型构造 constructor + type 3. constructor + “参数名” 直接通过参数名
-
必须知道, 只要我们在配置文件中配置了bean 无论我们使用不使用, 他直接都帮我们实例化好了, 也就是无论我们是否getBean()他都已经创建好所有的bean了, 并且创建的只有一个, 即使我们在代码中get相同的bean俩次, 但是获得的是一个
使用依赖注入有俩种方式:
- 属性setter注入: 指 IoC 容器使用 setter 方法注入被依赖的实例。通过调用无参构造器或无参 static 工厂方法实例化 bean 后,调用该 bean 的 setter 方法,即可实现基于 setter 的 DI
- 构造方法注入: 指 IoC 容器使用构造方法注入被依赖的实例。基于构造器的 DI 通过调用带参数的构造方法实现,每个参数代表一个依赖
-
需要让属性有 public 权限或者 setter 有 public 权限
-
基本数据类型 + String 用 value,其他引用类型用 ref
-
如果要使用集合,有 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
XXX
YYY