Spring Core-IOC

目录

目标

IOC

IOC定义

IOC容器

Bean

bean scope bean的使用范围

自定义bean的本质

AOP

事务


目标

介绍springcore中的IOC,阐述通过源码了解的原理。

IOC

IOC定义

IOC或者DI是仅可以通过[构造函数参数][工厂方法参数][由构造函数或工厂方法生成的实例的setter方法]3种方式[很多对象构建依赖关系]的过程
因为这个过程是[对象自己控制依赖对象的实例化]的彻底反转,因此起名为控制反转IOC

IOC容器

IOC容器是org.springframework.context.ApplicationContext的一个具体实例,根据配置信息进行实例化/配置/组装bean,输出一个全配置性且可运行的系统。

来自spring官网的图示

相关的包

  • org.springframework.beans/context;

相关接口

  • BeanFactory,提供管理各种对象的配置能力;
  • ApplicationContext,是BeanFactory的子接口,添加了对新特性的集成,如AOP。
  • FactoryBean接口,在BeanFactory中使用,负责生成特定类型bean。

Bean

BeanDefination

在IOC容器中,所有bean都以BeanDefination形式表现的。

创建一个beanDefination,就相当于获取到一个[通过beandifination创建class的很多实例]的秘诀;不仅可以控制实例的依赖和配置,而且可以控制实例的scope。

包含关于bean的元数据

  • 全路径class名称
  • 在IOC容器内的行为配置信息,如scope lifecycle等
  • 对其他bean的引用,成为合作者或依赖
  • 创建实例时的配置信息,如创建线程池时对线程数量的配置

实例化

构造函数的方式

静态工厂方法,bean的class中有静态工厂方法

实例化工厂方法

bean scope bean的使用范围

singleton 单例

(Default) Scopes a single bean definition to a single object instance per Spring IoC container.

默认配置,该scope的bean定义,在每个IOC容器中生成一个单例对象。

来自spring官网的图示

prototype 原型

Scopes a single bean definition to any number of object instances.

当bean定义的实例被需要时,就会新建一个对象实例。

来自spring官网图示

web相关

request

Scopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
每一个HTTP请求都具有一个独立的对象实例。

session

Scopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
每一个HTTP会话都具有一个独立的对象实例

globalSession

Scopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a Portlet context. Only valid in the context of a web-aware Spring ApplicationContext.

application

Scopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.
每个ServletContext具有一个独立的对象实例

websocket

Scopes a single bean definition to the lifecycle of a WebSocket. Only valid in the context of a web-aware Spring ApplicationContext.

web范围bean的注入需要DispatcherServlet RequestContextListener RequestContextFilter:使用name方式,将HTTP请求需要的bean绑定到HTTP请求的当前线程中,包括request session scope的bean。

自定义bean的本质

自定义bean的本质就是自定义生命周期扩展点

具体bean的生命周期回调lifecycle callback

  • 初始化回调:当bean配置的属性依赖,已经由IOC容器通过setter设置完成后,会调用bean回调方法。
    • 最佳实践为:使用方法上添加@PostConstruct或者bean配置init-method
    • 不建议使用
      org.springframework.beans.factory.InitializingBean
      void afterPropertiesSet() throws Exception;
  • 解构回调:当IOC容器正在销毁时,调用bean的回调方法。
    • 最佳实践为:方法上添加@PreDestroy或bean配置destroy-method
    • 不建议使用接口
      org.springframework.beans.factory.DisposableBean
      void destroy() throws Exception;

所有bean实例初始化前后的处理

BeanPostProcessor

  • postProcessBeforeInitialization 在当前新建bean的所有初始化回调之前
  • postProcessAfterInitialization 在当前新建bean的所有初始化回调之后

举例

CommonAnnotationBeanPostProcessor初始化回调前,@Resource根据beanName依赖注入,初始化@PostConstruct方法执行
AutowiredAnnotationBeanPostProcessor初始化回调前,对使用@autowired @value注解的field、setter进行依赖注入

ConfigurationPropertiesBindingPostProcessor

#postProcessBeforeInitialization

初始化回调前,为@ConfigurationProperties相关的filed赋值

AbstractAdvisingBeanPostProcessor

#postProcessAfterInitialization

在所有初始化回调后,生成代理

BeanFactory初始化后进行扩展

BeanFactoryPostProcessor

BeanFactory初始化后,进行Component扫描等工作,加载bean,但不进行实例化。

举例

集成到spring的中间件会在此做些扩展,如mybatis按照路径规则扫描并向beanfactory注册bean。

Aware

applicationContextAware IOC容器创建实例后调用该接口实现类的回调setApplicationContext

beanNameAware IOC容器创建实例并设置属性依赖后,调用回调方法setBeanName,然后调用初始化回调方法。

如何在@bean方法中获取到某种类型的所有bean?

例如我想获取到所有RedisTemplate bean。

使用org.springframework.beans.factory.ObjectProvider


	@Bean
	public Object test(ObjectProvider<RedisTemplate[]> tps) {
		RedisTemplate[] ifAvailable = tps.getIfAvailable();
		System.out.println();
		return null;
	}

Spring中有用的技巧

  • 扫描classpath并获取符合要求的类

使用到的类:ClassPathScanningCandidateComponentProvider

public static void scannerPackage(String[] packages, TypeFilter[] typeFilters, Consumer<Class<?>> consumer) {
        ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
        for (TypeFilter filter : typeFilters) {
            scanner.addIncludeFilter(filter);
        }
        for (String pack : packages) {
            for (BeanDefinition bd : scanner.findCandidateComponents(pack)) {
                consumer.accept(Class.forName(bd.getBeanClassName()));
            }
        }
    }

AOP

详见后续章节

事务

详见后续章节

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值