IoC: Inversion of Control,控制反转。将程序创建Bean的权利反转给第三方。
DI: Dependency Injection,依赖注入。某个完整Bean需要依赖于其他Bean(或属性)的注入。
Spring依赖包:
1 | <dependency> |
Spring容器:ApplicationContext
实现类
ClassPathXmlApplicationContext:加载类路径下的xml配置的ApplicationContext
FileSystemXmlApplicationContext:加载磁盘路径下的xml配置的ApplicationContext
AnnotationConfigApplicationContext:加载注解配置类的ApplicationContextBeanFactory与ApplicationContext的关系
1)BeanFactory是Spring的早期接口,称为Spring的Bean工厂,ApplicationContext是后期更高级接口,称之为
Spring 容器;
2)ApplicationContext在BeanFactory基础上对功能进行了扩展,例如:监听功能、国际化功能等。BeanFactory的
API更偏向底层,ApplicationContext的API大多数是对这些底层API的封装;
3)Bean创建的主要逻辑和功能都被封装在BeanFactory中,ApplicationContext不仅继承了BeanFactory,而且
ApplicationContext内部还维护着BeanFactory的引用,所以,ApplicationContext与BeanFactory既有继承关系,又
有融合关系。
4)Bean的初始化时机不同,原始BeanFactory是在首次调用getBean时才进行Bean的创建,而ApplicationContext则
是配置文件加载,容器一创建就将Bean都实例化并初始化好。
Spring Bean基本配置:
- xml方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="" class="" name="" lazy-init="" scope="" init-method="" destroy-method="" factory-bean=""
factory-method="" abstract="" depends-on="" parent="" profile="" autowire="byType/byName">
<!--
id:beanName
class:Bean的全限定名
name:Bean的别名
lazy-init:是否延迟初始化
scope:Bean的作用范围
init-method:Bean的初始化方法
destroy-method:Bean的销毁方法
factory-bean:Bean的工厂Bean
factory-method:Bean的工厂方法
abstract:是否为抽象Bean
depends-on:若A类和B类的关联关系不明显,但是在获取A类的对象时,需要先初始化B类,来满足A类的初始化工作;
depends-on属性的作用就是,在实例化A类之前,先实例化指定的B类.
示例
<bean id="A" class=""/>
<bean id="B" depends-on="A" class=""/>
parent:继承的父Bean
profile:Bean的生效环境
autowire:自动注入
-->
<property name="" ref=""/> <!--引用类型注入-->
<property name="" value=""/> <!--普通类型注入-->
<!--集合注入-->
<property name="">
<list> <!--map、set等标签-->
<value>xxx</value>
</list>
</property>
<!--构造bean所需要的参数注入-->
<constructor-arg name="" ref=""/>
<constructor-arg name="" value=""/>
</bean>
</beans> - 注解方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22@Component:将类标识为Bean
@Repository:标识持久层Bean
@Service:标识服务层Bean
@Controller:标识控制层Bean
@Scope:Bean的作用范围
@Lazy:Bean是否延迟初始化
@PostConstruct:Bean的初始化方法
@PreDestroy:Bean的销毁方法
@Autowired:自动注入,通过类型匹配注入Bean,类型相同,再根据名字匹配
@Qualifier:指定Bean的名称,配合Autowired使用,参数注入可省略Autowired
@Value:普通值注入
@Resource:自动注入,非Spring框架注解
@DependsOn:Bean的依赖Bean
@Primary:提高Bean优先级
@Configuration:标识配置类,用于替换xml配置文件
@Bean:配置非自定义Bean,标识配置类中的方法,将该方法返回值注入到Spring容器中
@Import:导入其他配置类
@ComponentScan:扫描指定包及其子包下的Bean,xml为<context:component-scan base-package=""/>标签
@Profile:指定Bean的生效环境
@propertySource:加载外部属性文件,xml为<context:property-placeholder/>标签
@PropertySources:加载多个外部属性文件
Bean的实例化配置
Spring的实例化方式主要如下两种:
- 构造方式实例化:底层通过构造方法对Bean进行实例化
- 工厂方式实例化:底层通过调用自定义的工厂方法对Bean进行实例化
- 静态工厂方法实例化Bean:定义一个工厂类,提供一个静态方法用于生产Bean实例,再将该工厂类及其静态方法配置给Spring即可
- 实例工厂方法实例化Bean:需要先有工厂对象,在用工厂对象去调用非静态方法,所以在进行配置时,要先配置工厂Bean,在配置目标Bean
- 实现FactoryBean规范延迟实例化Bean:定义工厂实现FactoryBean,Spring会自动调用工厂的getObject方法将Bean放到Spring容器中
Spring创建Bean的流程:
- 通过BeanDefinition读取器读取Bean定义信息,封装成BeanDefinition对象
- 通过BeanDefinitionRegistry将BeanDefinition对象注册到BeanDefinitionMap中
- 执行BeanFactoryPostProcessor(Bean工厂后处理器)
- BeanFactoryPostProcessor是个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对BeanDefinition注册和修改的功能,动态修改BeanDefinitionMap
- 通过反射实例化Bean
- 执行BeanPostProcessor(Bean后处理器)
- BeanPostProcessor是个接口规范,实现了该接口的类只要交由Spring容器管理的话,那么Spring就会回调该接口的方法,用于对Bean实例化后的功能增强,动态修改Bean实例。
- 初始化Bean,进行属性填充、Aware接口属性注入等
- 将Bean放入SingletonsObjects(单例池)中
Spring解决循环依赖(Bean1需要Bean2,Bean2需要Bean1):利用三级缓存
- 实例化Bean1后,将当前Bean1放入三级缓存,初始化时需要Bean2,遍历缓存,发现都没有,则进行创建Bean2
- 实例化Bean2后,将当前Bean2放入三级缓存,初始化时需要Bean1,遍历缓存,发现三级缓存中有Bean1,从三级缓存中获取Bean1,将Bean1放入二级缓存
- Bean2创建完毕,放入一级缓存
- Bean1从一级缓存中获取Bean2,完成创建
三级缓存:
- 三级:存放已实例化但未初始化Bean
- 二级:存放已被引用的Bean
- 一级:存放完成创建的Bean
Spring整合MyBitis
xml方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--mybatis和spring集成的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!--jdbc和spring集成依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
<!--druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
</dependency>1
2
3
4
5
6
7
8
9
10
11
12
13
14<!--配置数据源-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</bean>
<!--配置SqlSessionFactoryBean-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--配置Mapper包扫描-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.zzr.mapper"></property>
</bean>注解方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30<!--mybatis的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--mybatis和spring集成的依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.1</version>
</dependency>
<!--mysql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.32</version>
</dependency>
<!--jdbc和spring集成依赖-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.3.23</version>
</dependency>
<!--druid数据源依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.15</version>
</dependency>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20//配置类
//组件扫描
//mapper扫描
public class ApplicationContextConfig {
//配置数据源
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
//省略部分代码
return dataSource;
}
//配置SqlSessionFactoryBean
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);
return sqlSessionFactoryBean;
}
}Spring整合MyBatis原理:
- 配置SqlSessionFactoryBean作用是向容器中提供SqlSessionFactory,SqlSessionFactoryBean实现了FactoryBean(工厂Bean)和InitializingBean(初始化)两个接口,所以会自动执行FactoryBean里的getObject() 和InitializingBean里的afterPropertiesSet()方法,afterPropertiesSet()创建SqlSessionFactory对象,getObject()返回SqlSessionFactory对象,存储到Spring容器中。
- 配置MapperScannerConfigurer作用是扫描Mapper,向容器中注册Mapper对应的MapperFactoryBean,MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor(Bean工厂后处理器)和InitializingBean(初始化)两个接口,会在postProcessBeanDefinitionRegistry方法中向容器中注册MapperFactoryBean
- MapperFactoryBean为FactoryBean,Spring会自动执行getObject()方法,getObject()方法执行getSqlSession().getMapper()将Mapper对象注册到容器
- 本文作者: zzr
- 本文链接: http://zzruei.github.io/2023/12881e6aaa.html
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!