《SpringIOC》
目录
一、控制反转
概念
IOC全称是Inversion of Control,控制反转。它是一种设计思想,由容器将设计好的对象交给容器控制,而非对象内部直接new。有了IOC容器后,把创建和查找依赖对象的控制权交给了容器,由容器进行注入对象,所以对象与对象之间是松散耦合,这样也方便测试,利于功能复用,更重要的是使得程序的整个体系结构变得非常灵活。
原理
反射和工厂模式,反射原理使得我们通过对象的描述信息可生产出完整的对象,工厂模式使得IOC代码更加松耦合更合理的生产Bean对象。
DI(Dependency Injection——依赖注入)
IOC的一个重点是在系统运行中,动态的向某个对象提供它所需要的其他对象,这一点就是通过DI来实现的,即DI是实现IOC的主要技术途径。
二、Spring Bean
基本应用
- com.hpr.entity.User;
package com.hpr.entity;
import org.springframework.stereotype.Component;
//@Component注解表示将该类的对象创建权限交与Spring管理
@Component
public class User {
private int id;
private String name;
private int age;
private String phone;
public User() {
}
public User(int id, String name, int age, String phone) {
this.id = id;
this.name = name;
this.age = age;
this.phone = phone;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", phone='" + phone + '\'' +
'}';
}
}
- com.hpr.test.Test1;
package com.hpr.test;
import com.hpr.entity.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
//@SpringBootTest注解指定当前类为单元测试类,启动该类时会自动关联整个项目并执行该类下所有单元测试
@SpringBootTest
public class Test1 {
//依赖注入,将其他bean注入到当前类中
@Autowired
private User user;
//单元测试
@Test
public void testBean() {
System.out.println(user);
}
}
经验分享
maven项目中一般将单元测试代码写于test文件夹中。
- 执行单元测试。
执行结果
el表达式(结合@Value注解给定属性默认值)
- application.yml;
testUser:
name: Alice
- com.hpr.entity.User;
...
@Component
public class User {
//@Value注解指定默认值
@Value("1001")
private int id;
//${}引用项目全局参数
@Value("${testUser.name}")
private String name;
private int age;
private String phone;
...
}
- 执行单元测试。
执行结果
实例化方式
@Component默认采用无参构造进行初始化,并使用反射机制进行参数值设置,若想要灵活进行前置逻辑处理,可采用工厂模式。
- 删除或注释掉@Component注解(工厂模式不能与@Component同用);
...
//@Component
public class User {
...
}
- com.hpr.config.GlobalConfig
package com.hpr.config;
import com.hpr.entity.User;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//@Configuration表明当前是一个配置类
@Configuration
public class GlobalConfig {
//@Bean注解指定该类创建对象的工厂方法
@Bean
public User getUser() {
User user = new User();
user.setId(1002);
user.setName("Bob");
user.setAge(20);
user.setPhone("19938203135");
return user;
}
}
- 执行单元测试。
执行结果
显然,使用工厂模式依然可对JavaBean进行初始化设置(但@Value注解指定的值会覆盖前值)。
生命周期
针对Bean创建——>使用——>卸载的过程,Spring提供了两个注解指定其初始化及销毁方法。
- 添加方法;
...
public class User {
...
//初始化调用方法
@PostConstruct
public void init() {
System.out.println("User实例创建成功!");
}
//销毁时调用方法
@PreDestroy
public void destroy() {
System.out.println("User实例销毁成功!");
}
}
- 执行单元测试。
执行结果
作用域(Scope)
-
singleton(默认):单例模式,在整个Spring IOC容器中,使用singleton定义的Bean将只有一个实例;
-
prototype:原型模式,每次通过容器的getBean方法获取Bean时,都将产生一个新的Bean实例;
-
request:对于每次HTTP请求,使用request定义的Bean都将产生一个新实例(Web环境)。
-
session:对于每次HTTP Session,用法和使用时机同上。
...
@Scope("singleton")
public class User {
...
}
延迟加载(Lazy)
使用Spring注解是将bean的管理权交与Spring,但默认情况下,在启动时就加载所有类并创建bean会导致启动缓慢,想要使用时再加载该类,用@Lazy注解该类即可。
...
@Lazy
@Scope("singleton")
public class User {
...
}
总结
重点
- SpringIOC概念及主要实现手段;
- SpringBean:实例化方式、生命周期、el表达式、作用域、延迟加载。
难点
- SpringBean:实例化方式、生命周期、el表达式、作用域、延迟加载。