IOC和AOP是Spring的两大核心思想
一、IOC定义
Spring是包含了众多工具方法的IOC容器
IOC:(Inversion of Control)控制反转,也就是说Spring是控制反转的容器,
什么是控制反转呢?
本来需要对象时候,传统开发模式通过自己new对象,现在可以把创建对象任务交给IOC容器,程序只需要依赖注入就可以。Spring就是一个IOC容器,也可以称为Spring容器
二、IOC底层实现原理
Spring IOC的底层实现原理
1.读取配置 ,扫描类,将类的信息封装成BeanDefinition
2.通过反射创建对象
3.自动注入依赖(DI)
4.执行初始化方法,把单例Bean放到线程池供全局使用
核心技术:反射(动态创建对象)、BeanFactory(工厂模式)、设计模式(单例/适配器等),最终实现对象解耦和统一管理。
IOC 到底靠什么实现:
核心:
通过反射创建对象,通过BeanDefinition存储元信息,靠Map缓存实现单例
三、IOC底层使用的核心技术及设计模式
三大核心技术:
配置解析:读取XML配置文件,/@Component,@Bean注解,解析出所有Bean的元数据(作用域,依赖关系等等),结果封装成BeanDefinition
反射:无需new对象,Spring IOC 通过反射实现创建对象,依赖注入
工厂模式:IOC容器的核心是BeanFactory,负责Bean的创建,管理
设计模式(解耦核心):
1.工厂模式(Factory)
BeanFactory、ApplicationContext,负责统一创建 Bean;BeanFactory是简单工厂,FactoryBean是工厂 Bean,用来生产复杂对象。2.单例模式(Singleton) Bean 默认 scope=singleton,依靠**单例池(一级缓存 ConcurrentHashMap)**实现,保证全局只创建一份 Bean 实例。
3.原型模式(Prototype)
@Scope("prototype"),每次获取 Bean 新建对象。4.适配器模式(Adapter) 适配多种配置来源:XML、注解、JavaConfig,统一解析转换成
BeanDefinition;5.代理模式 IOC 本身不直接用,AOP 核心依靠动态代理(JDK 动态代理、CGLIB)。
四、DI定义
DI(Dependency Injection)依赖注入:容器在运行期间动态为程序提供运行所依赖的资源,称之为依赖注入
IOC和DI关系:
IOC是思想,DI是实现方式,IOC是把对象交给Spring管理,DI是容器自动注入依赖
五、Bean的存储
把某个对象交给IOC容器管理需要加注解:
1.类注解:
@Controller(控制器存储)控制层,接收请求,对接收的请求进行处理,进行响应
@Service(服务存储)业务逻辑层,处理具体业务逻辑
@Repository(仓库存储)数据访问层,数据访问操作
@Component(组件存储)
@Configuration(配置存储)
2.方法注解:
@Bean
方法注解要配合类注解才能使用,多个同样对象可以提高名称获取对象,还可以重命名
如何从Spring容器获取对象
ApplicationContext:Spring上下文:
因为对象都交给Spring管理了,获取对象也要从Spring中获取,就先要获取Spring的上下文,上下文指当前运行的环境,可以看作是一个容器,容器存了很多内容,内容是当前运行的环境
ApplicationContext VS BeanFactory
1.从继承关系和功能来说:Spring容器有两个顶级接口,一个是ApplicationContext另一个是BeanFactory,BeanFactory提供基础访问容器的功能,而ApplicationContext是BeanFactory的子类,除了继承它的功能之外,还添加对国际化支持,资源访问支持,事件传播等方面支持
2.性能来说:ApplicationContext一次性加载并且初始化所有Bean对象,BeanFactory是需要哪个加载哪个,更加轻量。
想要 SpringBoot 不加载某个 Bean有几种方案:
第一种,在启动类
@ComponentScan配置 excludeFilters,扫描阶段直接排除目标类;第二种使用条件注解,比如
@ConditionalOnProperty,依靠配置文件条件控制是否实例化; 第三种,如果是配置类通过@Bean注册的对象,可以直接删掉对应的 Bean 方法。第四种,使用
@Lazy只是延迟加载,不能完全不加载Bean。
六、DI详解三种注入方式
DI(Dependency Injection)依赖注入
三种方式:
1.属性注入:
通过@Autowired
优点:
- 简单方便
缺点:
- 只能用于IOC容器,非IOC容器不可以,只有在使用时候才会出现空指针异常
- 不能注入一个Final属性
2.构造方法注入:
优点:
- 可以注入Final对象
- 注入对象不会被修改
- 因为构造方法在类加载阶段就执行,依赖在构造方法中执行,使用依赖对象在使用前一定会完全初始化
- 通用性好,构造方法JDK支持,任何框架都适用
缺点:
- 注入多个对象,代码繁琐
3.Setter方法注入:
优点:
- 方便在类实例后,重新对对象进行配置和注入
缺点:
- 不能注入Final修饰属性
- 注入对象可能会改变,因为Setter方法可以多次调用,有修改风险
@Autowired存在问题:一个类型存在多个Bean,使用@Autowired会存在异常
解决方案:
1@Primary
2.@Qulifier
3.@Resource
@Autowird与@Resource区别:1.@Autowird按照类型注入,@Resource按照名称注入,支持更多参数设置例如name;
2.@Autowird是Spring框架提供的注解,@Resource是JDK提供的注解







