在springcacheinvokecontext中没找到field_spring中的@Autowired注解

先看个最常用的示例代码,介绍完整流程

a52f9bbd600f7d61bdf527420650141c.png

@Autowired简单例子

一.spring容器实例化的时候,如web容器AnnotationConfigServletWebServerApplicationContext构造方法中,new一个新对象AnnotatedBeanDefinitionReader实例,而AnnotatedBeanDefinitionReader又注册了ConfigurationClassPostProcessor(BeanFactory后置处理器)、AutowiredAnnotationBeanPostProcessor(Bean后置处理器)的类定义信息BeanDefinition到容器中

二.spring容器执行刷新refresh过程中,invokeBeanFactoryPostProcessors(beanFactory),开始统一执行BeanFactory的后置处理器

1.找到容器中注册的所有BeanFactory后置处理器的BeanDefinition对象,实例化ConfigurationClassPostProcessor对象到容器中

2.执行BeanFactory后置处理器的方法,ConfigurationClassPostProcessor方法中扫描所有注解信息将扫描到的class(包括HelloController和HelloService的class)封装成BeanDefinition,注册进容器中

三.注册容器中bean后置处理器对象,registerBeanPostProcessors(beanFactory),找到所有bean后置处理器的BeanDefinition,实例化bean后置处理器AutowiredAnnotationBeanPostProcessor对象到容器中

四.剩余的BeanDefinition实例化对象,finishBeanFactoryInitialization(beanFactory),这里包括像HelloController和HelloService这样的类

1.实例化HelloController对象,也就是调用构造方法的过程

2.初始化HelloController对象,也就是填充属性值,调用set的过程

1).统一执行bean的后置处理器方法,AutowiredAnnotationBeanPostProcessor(InstantiationAwareBeanPostProcessor-BeanPostProcessor)#postProcessProperties()方法

2).循环属性,找到有@Autowired的注解的属性(也就是helloService属性),封装成AutowiredFieldElement对象,保存在集合中;集合封装成InjectionMetadata对象

3).循环InjectionMetadata对象,找到容器中是HelloService类型的BeanNames(默认找不到会报错,找到多个也会报错,区分不了注入哪个)

4).根据beanName:helloService,从容器中取helloService名称的对象,beanFactory.getBean(beanName),这个时候如果还没有helloService对象,开始进入helloService对象的创建过程

5).helloService对象创建完成后,反射设置值field.set(bean, value),注解属性设置完成

五.@Autowired注解可以和@Qualifier(用以指名区分多个类型一样的bean)、@Lazy(true的时候,会注入临时生成的代理对象,区别于aop代理对象,只有在真正执行目标方法的时候才会去容器内拿真正bean实例,可用于解决循环依赖,区别于三级缓存的解决方案)搭配使用

六.常用属性注解

e18afed152a2870f152cb0156a8d153e.png

常用属性注解

七.@Autowired可以注入自己,也即可以在helloService代码中@Autowired helloService;在AOP动态代理场景中,@EnableAspectJAutoProxy(exposeProxy=false)默认为false,动态代理类不暴露出来的情况下,helloService中a、b两个方法,b方法有显示的@Transaction事务注解,a方法调用b方法,事务注解@Transaction是不生效的,因为在a和b方法中,this当前对象是真实对象而非容器代理对象,所以可以利用自己注入自己的容器代理对象,等同于直接调用context.getBean("helloService")

八.在使用spring+springMVC的web工程中,存在父子两个容器,父容器包含service+dao的bean对象,子容器包含controller的bean对象,子容器可以取到父容器的值,父容器取不到子容器的值,所以导致在service中@Autowired controller会报错!但springboot中,不存在父子两个容器,一个容器搞定所有事,controller和service可以相互注入

九.@Autowired特殊对象,如spring容器,AbstractApplicationContext#prepareBeanFactory,注册依赖解析内置了BeanFactory,ResourceLoader,ApplicationEventPublisher,ApplicationContext实例;AnnotationConfigServletWebApplicationContext#postProcessBeanFactory,注册依赖解析内置了web相关的实例ServletRequest,ServletResponse,HttpSession,WebRequest四个对象,所以在spring所有bean中,可以直接@Autowired注入这几个特殊对象实例

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值