Spring框架1--IoC
Spring框架之IoC

Spring的后处理器 待补充~
- BeanFactoryPostProcessor
- BeanPostProcessor
Bean的生命周期

具体可见图解:点击这里
补充:
- Aware
- Ordered
Bean的加载方式
1.xml方式
<?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">
<!--声明自定义bean-->
<bean id="bookService" class="com.azy.service.impl.BookServiceImpl"
scope="singleton"/>
<!--声明第三方开发bean-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"/>
</beans>
2.xml文件+Component注解
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描bean-->
<context:component-scan base-package="com.azy"/>
</beans>
类上面加上@Component注解
@Component
//@Service,@Controller,@Repository为@Component衍生注解,效果相同
public class BookServiceImpl implements BookService {
}
//第三方Bean
@Component
public class DruidBean {
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("");
dataSource.setUrl("");
dataSource.setUsername("");
dataSource.setPassword("");
return dataSource;
}
}
3.纯注解
//配置类:
//注解开发,替换配置文件xml文件
@Configuration
@ComponentScan("com.azy") //包扫描
public class SpringConfig {
}
扩展:
FactoryBean接口产生BeanImportSource注解可以加载旧的配置文件@Configuration
@ComponentScan("com.azy") //包扫描
@ImportResource("applicationContext-config.xml")
public class SpringConfig {
}
Configuration注解默认有个参数proxyBeanMethods=true可以保障调用此方法得到的对象是从容器中获取的而不是重新创建的
4.Import注解导入
//配置类:
//注解开发,替换配置文件xml文件
@Configuration
@ComponentScan("com.azy") //包扫描
@Import(DruidBean.class)
public class SpringConfig {
}
Import可以导入普通类或者配置类,导入的普通类或者配置类不用再加@Component注解:
//第三方Bean
//@Component
public class DruidBean {
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("");
dataSource.setUrl("");
dataSource.setUsername("");
dataSource.setPassword("");
return dataSource;
}
}
5.Spring容器注册
public class AppImport {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(SpringConfig.class);
ctx.register(Cat.class);//注册
//……
}
}
6.Import注解导入接口
ImportSelector接口:
public class MyImportSelector implements ImportSelector {
@Override
public String[] selectImports(AnnotationMetadata importingClassMetadata) {
return new String[0];
}
}
//可以根据importingClassMetadata参数来判断导入该实现类所在的类的条件,
//从而返回要进行创建的Bean的类名
ImportBeanDefinitionRegistrar接口
public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
}
}
//通过BeanDefinition的注册器注册实名bean,实现对容器中bean的裁定,
//例如对现有bean的覆盖,进而达成不修改源代码的情况下更换实现的效果
BeanDefinitionRegistryPostProcessor接口
public class MyPostProcessor implements BeanDefinitionRegistryPostProcessor {
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
BeanDefinition beanDefinition = BeanDefinitionBuilder
.rootBeanDefinition(BookServiceImpl.class)
.getBeanDefinition();
registry.registerBeanDefinition("bookService", beanDefinition);
}
}
//通过BeanDefinition的注册器注册实名bean,实现对容器中bean的最终裁定
Bean的加载控制
1.Spring容器注册
2.Import注解导入接口
ImportSelector接口ImportBeanDefinitionRegistrar接口BeanDefinitionRegistryPostProcessor接口
3.Conditional衍生注解

这些衍生注解都是SpringBoot实现的
@Component
//@ConditionalOnClass(Book.class)
//ConditionalOnClass可以直接导入类,但是ConditionalOnMissingClass不可以,建议使用name
@ConditionalOnClass(name="com.azy.pojo.Book")//有这个类才加载下面的BookService
@ConditionalOnMissingClass("com.azy.pojo.Book")//没有这个类才加载下面的BookService
public class BookServiceImpl implements BookService {
}
第三方Bean:
//有数据库驱动的时候才加载DataSource
@Component
public class DruidBean {
@Bean
@ConditionalOnClass(name="com.mysql.jdbc.Driver")
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("");
dataSource.setUrl("");
dataSource.setUsername("");
dataSource.setPassword("");
return dataSource;
}
}
Spring自定义标签解析 待补充~
Spring注解的解析原理
Spring注解的解析主要包含两种方式(即Bean的加载方式中的2和3):
配置文件中自定义标签:
<context:component-scan base-package="com.azy"/>
使用xml方式配置组件扫描,而component-scan是一个context命名空间下的自定义标签,所以要找到对应的命名空间处理器NamespaceHandler和解析器,查看spring-context包下的spring.handlers文件:
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
查看 ContextNamespaceHandler 类 :
public void init() {
this.registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
}
将ComponentScanBeanDefinitionParser进行了注册,对其源码进行跟踪,最终将标注的@Component的类,生成对应的BeanDefiition进行了注册。
- 配置类上添加
ComponentScan注解
使用配置类配置组件扫描,使用AnnotationConfigApplicationContext容器在进行创建时,内部调用了如下代码, 该工具注册了几个Bean后处理器:
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);

其中,ConfigurationClassPostProcessor 实现了 BeanDefinitionRegistryPostProcessor ,经过一系列源码调用,最终也指到了 ClassPathBeanDefinitionScanner 的 doScan 方法,与xml方式最终终点一致。

Spring整合Mybatis原理
xml方式整合:
<?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"> <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</bean>
<bean class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="druidDataSource"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.azy.ioc.mapper"/>
</bean> </beans>
主要是依靠
SqlSessionFactoryBean和MapperScannerConfigurer来进行整合的:SqlSessionFactoryBean的作用是向容器中提供SqlSessionFactorypublic class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {
//这里实现了FactoryBean接口,getObject方法获取Bean
public void afterPropertiesSet() throws Exception {
//创建SqlSessionFactory对象
this.sqlSessionFactory = this.buildSqlSessionFactory();
}
public SqlSessionFactory getObject() throws Exception {
return this.sqlSessionFactory;
}
}
MapperScannerConfigurer的作用是扫描Mapper,向容器中注册Mapper对应的MapperFactoryBean://MapperScannerConfigurer实现了BeanDefinitionRegistryPostProcessor,在postProcessBeanDefinitionRegistry方法中利用ClassPathMapperScanner向容器中注册MapperFactoryBean
class MapperScannerConfigurer implements BeanDefinitionRegistryPostProcessor, InitializingBean{
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
scanner.scan(StringUtils.tokenizeToStringArray(this.basePackage, ",; \t\n"));
}
} //ClassPathMapperScanner继承了ClassPathBeanDefinitionScanner
class ClassPathMapperScanner extends ClassPathBeanDefinitionScanner {
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
if (beanDefinitions.isEmpty()) {
} else {
this.processBeanDefinitions(beanDefinitions);
}
}
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
//设置Mapper的beanClass是org.mybatis.spring.mapper.MapperFactoryBean
definition.setBeanClass(this.mapperFactoryBeanClass);
definition.setAutowireMode(2); //设置MapperBeanFactory 进行自动注入
}
}
MapperFactoryBean的作用就是产生对应的Mapper,其底层实际上还是调用的Mybatis的方法:public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
public MapperFactoryBean(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionTemplate = this.createSqlSessionTemplate(sqlSessionFactory);
}
public T getObject() throws Exception {
return this.getSqlSession().getMapper(this.mapperInterface);
}//这里getSqlSession利用自动注入,然后再利用sqlSession调用getMapper
}
注解方式:
@Component
@MapperScan("com.azy.annotation.mapper")
public class MybatisConfig { @Bean //形参可以自动装配
public SqlSessionFactoryBean sqlSessionFactoryBean(DataSource dataSource) {
SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setTypeAliasesPackage("com.azy.annotation.pojo");
sqlSessionFactory.setDataSource(dataSource);
return sqlSessionFactory;
}
}
这里主要看
MapperScan注解,它导入了MapperScannerRegistrar:@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
public @interface MapperScan {
}
MapperScannerRegistrar实现了ImportBeanDefinitionRegistrar接口:public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware { }
其中的
registerBeanDefinitions方法向容器中注册了Mapper对应的MapperFactoryBean,与前面相同。
Spring框架1--IoC的更多相关文章
- Spring框架(3)---IOC装配Bean(注解方式)
IOC装配Bean(注解方式) 上面一遍文章讲了通过xml来装配Bean,那么这篇来讲注解方式来讲装配Bean对象 注解方式需要在原先的基础上重新配置环境: (1)Component标签举例 1:导入 ...
- Spring框架之IOC(控制反转)
[TOC] 第一章Spring框架简介 IOC(控制反转)和AOP(面向方面编程)作为Spring框架的两个核心,很好地实现了解耦合.所以,简单来说,Spring是一个轻量级的控制反转(IoC)和面向 ...
- Spring框架中IoC(控制反转)的原理(转)
原文链接:Spring框架中IoC(控制反转)的原理 一.IoC的基础知识以及原理: 1.IoC理论的背景:在采用面向对象方法设计的软件系统中,底层实现都是由N个对象组成的,所有的对象通过彼此的合作, ...
- Spring框架的IOC核心功能快速入门
2. 步骤一:下载Spring框架的开发包 * 官网:http://spring.io/ * 下载地址:http://repo.springsource.org/libs-release-local/ ...
- (精简)Spring框架的IoC(替代工厂类实现方法)和AOP(定义规则,约定大于配置)
Spring的核心框架主要包含两个技术,分别用来处理工厂类,以及事务处理和连接管理的. 两大核心概念 1) IoC:控制反转,在现在的开发中,如果想建立对象并设置属性,是需要先new对象,再通过se ...
- 初识Spring框架实现IOC和DI(依赖注入)
学习过Spring框架的人一定都会听过Spring的IoC(控制反转) .DI(依赖注入)这两个概念,对于初学Spring的人来说,总觉得IoC .DI这两个概念是模糊不清的,是很难理解的, IoC是 ...
- Spring框架(2)---IOC装配Bean(xml配置方式)
IOC装配Bean (1)Spring框架Bean实例化的方式提供了三种方式实例化Bean 构造方法实例化(默认无参数,用的最多) 静态工厂实例化 实例工厂实例化 下面先写这三种方法的applicat ...
- 十七、Spring框架(IOC/DI)
一.Spring框架 Spring是一个基于IOC和AOP的结构J2EE系统的框架. 1.IOC反转控制是Spring的基础(Inversion Of Control).也就是说创建对象由以前的程序员 ...
- Spring框架的IOC之注解方式的快速入门
1. 步骤一:导入注解开发所有需要的jar包 * 引入IOC容器必须的6个jar包 * 多引入一个:Spring框架的AOP的jar包,spring-aop的jar包 2. 步骤二:创建对应的包结构, ...
- Spring框架之IoC和AOP
Spring框架简介: 2003年2月,Spring框架正式成为一个开源项目,并发布于SourceForge中.致力于Java EE应用的各种解决方案,而并不是仅仅专注于某一层的方案,是企业应用开发的 ...
随机推荐
- TCP/IP RTT算法比较
TCP重传机制Timeout特点: 设长了,重发就慢,效率和性能差: 设短了,重发就快,可能导致没有丢就重发,增加网络拥塞,导致更多的超时,更多的超时导致更多的重发. TCP协议引入2个概念: RTT ...
- Redis 异步客户端选型及落地实践
作者:京东科技 王晨 Redis异步客户端选型及落地实践 可视化服务编排系统是能够通过线上可视化拖拽.配置的方式完成对接口的编排,可在线完成服务的调试.测试,实现业务需求的交付,详细内容可参考:htt ...
- 12月6日内容总结——BOM、DOM、两者查找标签的方式和操作标签的方式、操作class和css的方法、事件、jQuery类库
目录 一.BOM操作 BOM概念 window对象 window的子对象 navigator对象(了解即可) screen对象(了解即可) history对象(了解即可) location对象 弹出框 ...
- 深度复盘-重启 etcd 引发的异常
作者信息: 唐聪.王超凡,腾讯云原生产品中心技术专家,负责腾讯云大规模 TKE 集群和 etcd 控制面稳定性.性能和成本优化工作. 王子勇,腾讯云专家级工程师, 腾讯云计算产品技术服务专家团队负责人 ...
- 【译】使用 ML.NET 进行机器学习 - 集群完整指南
原文 | Nikola M. Zivkovic 翻译 | 郑子铭 在之前的几篇文章中,我们探索了一些基本的机器学习算法.到目前为止,我们介绍了一些简单的回归算法,分类 算法.我们使用 ML.NET 实 ...
- C#NPOI操作Excel,实现Excel数据导入导出(支持多个sheet)
首先在项目中引用NPOI,通过管理NuGet程序包,搜索NPOI,选择版本2.3.0(支持.NET Framework 4.0)根据自己项目选择适当版本. 1.NpoiExcelHelper.cs ...
- python爬取丁香园疫情数据
毕设需求了就是说 导师要做关于时间线的- -看发展趋势 不得不今天又现学现卖 首先 创建一个python文件 python.file 引入一点资源 # 发送请求 import requests # 页 ...
- 利用ICSharpCode.SharpZipLib.dll解析 出错:“Wrong Local header signature: 0xFF8”
分析原因 利用ICSharpCode.SharpZipLib.dll解析APK时,进入APK的AndroidXml获取时出现报错 出错代码 using (ICSharpCode.SharpZipLib ...
- element-UI el-table动态显示隐藏列造成固定一侧的列(fixed=“left/right“)错误显示
问题原因:多个tabs共用一个实体,动态显示隐藏列 出现了固定在右侧的列(fixed="right")错位 [解决方案] 表格的重新布局,只要table数据发生变化的时候就重新渲染 ...
- LG P4717 【模板】快速莫比乌斯/沃尔什变换 (FMT/FWT)
\[C_k = \sum_{i|j=k}A_i B_j \] 这样的或卷积可以做一次 \(\text{FWT}\),把数组变为 \(\widehat{A}_i = \sum_{j\subseteq i ...