目录
一、spring核心
spring全家桶
spring、springmvc、springboot、springsecurity、springcloud
spring包含的子模块:
spring core ----- 最核心jar包 ioc、di
spring dao ----- 针对jdbc封装
spring orm ----- object relational mapping 对象关系映射思想
spring aop ----- 面向切面管理 (事务切面、日志切面、权限控制、自定义切面)
spring web ------ 针对servlet进行的封装,接收请求、响应数据给前端
spring context ---- 上下文环境
springmvc ---- spring webmvc ---包含spring core 、aop等
spring三大思想
IOC、DI、AOP
spring两大思想
IOC|DI、AOP
Spring Framework:Spring 的基础框架,可以视为 Spring 基础设施,基本上任何其他 Spring 项目都是以 Spring Framework 为基础的,其包含**IOC/DI**和**AOP**两大核心部分。
核心 | 描述 |
---|---|
IOC | Inversion of Control 的简写,译为"控制反转",指把创建对象过程交给 Spring 进行管理。 |
AOP | Aspect Oriented Programming 的简写,译为"面向切面编程"。AOP 用来封装多个类的公共行为,将那些与业务无关、却为业务模块所共同调用的逻辑封装起来,减少系统的重复代码,降低模块间的耦合度。另外,AOP 还解决一些系统层面上的问题,比如日志、事务、权限等。 |
二、IOC
2.1 IOC概念
IOC全称Inversion Of Control 控制反转,核心的作用就是将原来由开发人员来控制的对象管理操作交由Spring来管理,spring创建出来的对象,会放到spring的一个容器中存储,使用对象的时候可以从容器直接拿,这个容器就称为spring ioc容器。
简单来说:原来我们自己new对象的操作不在做了,而是由spring帮我们创建对象,创建出来的对象spring会放到一个容器中管理,我们用对象的时候,从容器中去拿就行了。
2.2 IOC容器初始化方式
- xml配置文件配置方式【使用读取xml中的bean来创建对象】
- 纯注解方式
2.3 类关系
- BeanFactory接口:这是 IOC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。
- ApplicationContext接口:BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。
- ClassPathXmlApplicationContext:通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象。
- AnnotationConfigApplicationContext:通注解方式创建 IOC 容器对象。
2.4 IOC控制反转思想
IOC(控制反转)是 Spring 框架的核心思想,其本质是将对象的创建、依赖装配和生命周期管理从应用程序代码转移到容器中完成。
inverse of control
控制权的反向转移。创建对象的权限转移给spring容器
(原来创建对象,是谁用谁创建,现在应该有spring容器创建,使用时从容器中获取)
User u1 = new User(); 创建需要消耗资源、存储消耗资源、回收消耗资源。
User u2 = new User(); 频繁的创建对象、销毁对象。
1、创建容器
2、将对象放到容器中
3、用的时候从容器中获取
4、不用了,归还对象到容器。
三、搭建spring环境
字不重要,看图
四、创建容器的两种方式
4.1通过类创建
package com.hl.springboot01;
import org.springframework.context.annotation.Configuration;
//@Configuration 配置文件类
@Configuration
public class MyConfig {
}
package com.hl.springboot01;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MyBeanTest {
@Test
public void createContainer(){
//读取配置文件类,创建ioc容器
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(MyConfig.class);
//context 即为容器对象
}
}
4.2通过配置文件创建
<?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">
<!-- 创建一个对象
id="对象名" class="类的全限定名"
同一个容器中,对象名不能重复
单例模式:一个类只有一个实例(对象) 默认 scope="singleton"
多例模式:一个类有多个实例对象 scope="prototype"
spring-web 环境 接受前端请求
request:一次request请求创建一个对象
session:一个会话共享一个对象
global-session:全局有效-->
<bean id="u1" class="com.hl.springboot01.pojo.User" scope="prototype"></bean>
</beans>
@Test
public void createContainer2(){
//读取配置文件,创建ioc容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
User user1 = context.getBean(User.class);
User user2 = context.getBean(User.class);
System.out.println(user1);
System.out.println(user2);
//只要不报空指针异常,就证明从容器中获取了对象
// System.out.println(user.toString());
}
五、容器内部创建对象
5.1配置类创建对象
创建javabean类
@Data
//创建当前类的对象,并交给spring容器进行管理
@Component
public class User {
private int id;
private String name;
}
在配置文件类定义组件扫描的包
//@Configuration 配置文件类
@Configuration
//定义组件扫描的包
@ComponentScan(basePackages = "com.hl.springboot01.pojo")
public class MyConfig {
}
5.2配置文件模式创建对象
<?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">
<!-- 创建一个对象
id="对象名" class="类的全限定名"
同一个容器中,对象名不能重复
单例模式:一个类只有一个实例(对象) 默认 scope="singleton"
多例模式:一个类有多个实例对象 scope="prototype"
spring-web 环境 接受前端请求
request:一次request请求创建一个对象
session:一个会话共享一个对象
global-session:全局有效-->
<bean id="u1" class="com.hl.springboot01.pojo.User" scope="prototype"></bean>
</beans>
5.3构造方法
5.4工厂方法
六、获取对象的过程
package com.hl.springboot01;
import com.hl.springboot01.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyBeanTest {
@Test
public void createContainer(){
//读取配置文件类 创建ioc容器
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext(MyConfig.class);
//context 即为容器对象
//从容器中获取对象
User user = context.getBean(User.class);
//只要不报空指针异常,就证明从容器中获取了对象
System.out.println(user.toString());
}
@Test
public void createContainer2(){
//读取配置文件,创建ioc容器
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("applicationContext.xml");
User user1 = context.getBean(User.class);
User user2 = context.getBean(User.class);
System.out.println(user1);
System.out.println(user2);
//只要不报空指针异常,就证明从容器中获取了对象
// System.out.println(user.toString());
}
}
七、对象的生命周期
对象的生命周期:对象创建到销毁的整个过程
7.1对象创建
单例模式:默认情况下,在创建ioc容器时,创建对象。
创建对象时,默认调用无参构造方法创建对象。 无参构造只执行一遍。
初始化方法(在对象创建后,自动调用的方法)。 初始化方法只执行一遍。
销毁前调用的方法(关闭ioc容器时,自动调用的) 。只执行一次。
懒加载:只针对单例模式有效。
懒加载:在首次使用对象时创建对象(而不是在创建容器时创建对象)。
多例模式下:可以创建很多对象,不是提前创建的对象,是使用是创建对象。
每获取一次对象,创建一个对象,执行一次构造方法,执行一次初始化方法。
7.2对象销毁
单例模式下,关闭容器时销毁。
多例模式下:对象 由 jvm虚拟机 垃圾回收器 在 后台进程自动销毁。
package com.hl.springboot02.pojo;
import lombok.Getter;
import lombok.Setter;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Getter
@Setter
//创建类的对象 对象名默认为类名(首字母变小写)
//@Component("对象名")
//多例模式
//@Scope(value = "prototype")
//懒加载
@Lazy
@Component("goods")
public class Goods {
private int id;
private String name;
private int price;
public Goods() {
System.out.println("goods....无参构造.......");
}
//@PostConstruct 初始化方法
@PostConstruct
public void init(){
System.out.println("init ..... 初始化方法");
}
//@PreDestroy 销毁前执行
@PreDestroy
public void destroy(){
System.out.println("destroy....销毁前执行");
}
}
@Test
public void objectLife(){
//单例模式下的对象 默认是在创建容器时,直接创建对象,销毁ioc容器时,销毁对象
AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(Springboot02Application.class);
// //获取对象
// //多例模式下的对象 默认是在获取对象时创建,由jvm虚拟机自动销毁
Goods goods = context.getBean("goods", Goods.class);
Goods goods2 = context.getBean("goods", Goods.class);
//
// //优雅的销毁容器
context.registerShutdownHook();
}
八、Bean的作用域
作用域 | 说明 |
---|---|
singleton | 默认作用域,每个 IoC 容器中仅存在一个共享实例 |
prototype | 每次请求(getBean() 或注入)都创建新实例 |
request | 每个 HTTP 请求创建一个实例(Web 环境) |
session | 每个 HTTP 会话共享一个实例(Web 环境) |
<!--
创建一个对象
id="对象名“
class="类的全限定名"
在同一个容器中,对象名不能重复
单例模式: 一个类只有一个实例(对象) 默认 scope="singleton"
多例模式:一个类有多个实例(对象) scope="prototype"
spring-web 环境 接收前端请求
request: 一次request请求创建一个对象
session: 一个会话共享一个对象
global-session: 全局有效
-->
<bean id="u1" name="u2,u3" class="com.hl.springboot01.pojo.User" scope="singleton"></bean>
九、从容器中获取对象的三种方式
// 方式一: 推荐 名称+类型
Goods goods = context.getBean("goods", Goods.class);
System.out.println(goods);
// 方式二: 名称 需要强制类型转换
Goods goods2 = (Goods)context.getBean("goods");
System.out.println(goods2);
// 方式三: 通过类型获取
Goods goods3 = context.getBean(Goods.class);
System.out.println(goods3);
@Getter
@Setter
//创建类的对象 对象名默认为类名(首字母变小写)
//@Component("对象名")
@Component("goods")
public class Goods {
private int id;
private String name;
private int price;
}
面试题
1.spring的三大核心思想
IOC di aop
2.IOC思想的理解
IOC全称Inversion Of Control 控制反转,核心的作用就是将原来由开发人员来控制的对象管理操作交由Spring来管理,spring创建出来的对象,会放到spring的一个容器中存储,使用对象的时候可以从容器直接拿,这个容器就称为spring ioc容器。
简单来说:原来我们自己new对象的操作不在做了,而是由spring帮我们创建对象,创建出来的对象spring会放到一个容器中管理,我们用对象的时候,从容器中去拿就行了。
3.IOC容器创建的两种方式
- xml配置文件配置方式【使用读取xml中的bean来创建对象】
- 纯注解方式
- BeanFactory接口:这是 IOC 容器的基本实现,是 Spring 内部使用的接口。面向 Spring 本身,不提供给开发人员使用。
- ApplicationContext接口:BeanFactory 的子接口,提供了更多高级特性。面向 Spring 的使用者,几乎所有场合都使用 ApplicationContext 而不是底层的 BeanFactory。
- ClassPathXmlApplicationContext:通过读取类路径下的 XML 格式的配置文件创建 IOC 容器对象。
- AnnotationConfigApplicationContext:通注解方式创建 IOC 容器对象。
4.创建对象的注解
@Component 类上使用 告诉 Spring:这个类是一个组件,帮我创建它的对象并管理!
@Bean 方法上使用,方法的返回值是对象,将返回的对象交给ioc容器管理。
告诉 Spring:调用这个方法,把返回的对象放进容器!
5.底层如何创建对象
构造方法(无参构造|有参构造)
工厂方法(静态工厂方法|实例工厂方法)
//创建对象 对象名 默认为方法名
//实例工厂方法
@Bean
public Category category(){
return new Category();
}
//静态工厂方法
@Bean
public static Category category2(){
return new Category();
}
6.对象何时创建、何时销毁、能否延迟创建
单例模式:默认情况下,在创建ioc容器时,创建对象。
创建对象时,默认调用无参构造方法创建对象。 无参构造只执行一遍。
初始化方法(在对象创建后,自动调用的方法)。 初始化方法只执行一遍。
销毁前调用的方法(关闭ioc容器时,自动调用的) 。只执行一次。
懒加载:只针对单例模式有效。
在首次使用对象时创建对象(而不是在创建容器时创建对象)。
多例模式下:可以创建很多对象,不是提前创建的对象,是使用是创建对象。
每获取一次对象,创建一个对象,执行一次构造方法,执行一次初始化方法。
单例模式下,关闭容器时销毁。
多例模式下:对象 由 jvm虚拟机 垃圾回收器 在 后台进程自动销毁。
7.从容器中获取对象的三种方式
// 方式一: 推荐 名称+类型
Goods goods = context.getBean("goods", Goods.class);
System.out.println(goods);
// 方式二: 名称 需要强制类型转换
Goods goods2 = (Goods)context.getBean("goods");
System.out.println(goods2);
// 方式三: 通过类型获取
Goods goods3 = context.getBean(Goods.class);
System.out.println(goods3);
8.bean的作用域范围
作用域 | 说明 |
---|---|
singleton | 默认作用域,每个 IoC 容器中仅存在一个共享实例 |
prototype | 每次请求(getBean() 或注入)都创建新实例 |
request | 每个 HTTP 请求创建一个实例(Web 环境) |
session | 每个 HTTP 会话共享一个实例(Web 环境) |
<!--
创建一个对象
id="对象名“
class="类的全限定名"
在同一个容器中,对象名不能重复
单例模式: 一个类只有一个实例(对象) 默认 scope="singleton"
多例模式:一个类有多个实例(对象) scope="prototype"
spring-web 环境 接收前端请求
request: 一次request请求创建一个对象
session: 一个会话共享一个对象
global-session: 全局有效
-->
<bean id="u1" name="u2,u3" class="com.hl.springboot01.pojo.User" scope="singleton"></bean>
9.相关的注解有哪些?各自作用?
容器配置注解
注解 | 作用 | 示例 |
---|---|---|
@Configuration | 标记该类为 配置类(相当于 XML 配置文件) | java @Configuration public class AppConfig { ... } |
@ComponentScan | 指定 Spring 扫描哪些包下的组件(@Component 、@Service 等) | java @ComponentScan("com.example") |
对象创建与管理
注解 | 作用 | 示例 |
---|---|---|
@Component | 通用注解,标记类为 Spring 管理的 组件(@Service /@Repository 的父注解) | java @Component public class UserService { ... } |
@Bean | 在配置类中定义方法,返回的对象由 Spring 管理(用于 第三方库的类) | java @Bean public DataSource dataSource() { ... } |
@Lazy | 延迟初始化(第一次使用时才创建对象) | java @Lazy @Component public class HeavyService { ... } |
@Scope | 指定 Bean 的作用域(singleton 、prototype 、request 等) | java @Scope("prototype") @Component public class Task { ... } |
生命周期回调
注解 | 作用 | 示例 |
---|---|---|
@PostConstruct | 初始化方法(相当于 init-method ) | java @PostConstruct public void init() { ... } |
@PreDestroy | 销毁前方法(相当于 destroy-method ) | java @PreDestroy public void cleanup() { ... } |
lombok简化代码(非spring注解)
注解 | 作用 | 示例 |
---|---|---|
@Data | 自动生成 getter /setter /toString /equals /hashCode | java @Data public class User { private String name; } |
@Getter | 仅生成 getter 方法 | java @Getter public class User { private String name; } |
@Setter | 仅生成 setter 方法 | java @Setter public class User { private String name; } |
@Test | JUnit 测试方法标记(不属于 Spring) | java @Test public void testMethod() { ... } |
@Before | 标记的方法会在 每个@Test 测试方法之前 自动执行 | 每个 @Test 前运行一次 |
@After | 标记的方法会在 每个@Test 测试方法之后 自动执行(无论测试是否抛出异常) | 每个 @Test 后运行一次 |