聊聊Spring中的无注解依赖注入

2023年 9月 27日 60.4k 0

声明:无注解依赖注入是我自己创造的概念

在我们使用Spring时,一般都会用@Autowired、@Resource注解来进行依赖注入,其实@Value注解也算是依赖注入,在源码里,@Autowired和@Value是在一块进行处理的,区别在于@Autowired找到的是Bean对象,@Value找到的是字符串,然后把找到的对象或字符串赋值给属性,所以本质上@Autowired和@Value区别不大。

@Value利用Spring EL表达式也可以找到Bean对象,本文就不详细描述了,关注我,后续分析

那在Spring中,可不可以不使用注解也能进行依赖注入呢?

其实在Spring整合Mybatis的源码中,就利用了无注解依赖注入,比如以下代码是MapperFactoryBean类的父类SqlSessionDaoSupport中的代码: image.png 在上述代码中存在两个set方法,这其实是两个set注入,但是在它的源码中,并没有使用@Autowired注解,那最终是如何完成set注入的呢?

我们再看一段源码: image.png 以上代码做了三件事件:

  • 给MapperFactoryBean中的sqlSessionFactory属性赋值,其实并没有真正的sqlSessionFactory属性,但是有setSqlSessionFactory方法
  • 给MapperFactoryBean中的sqlSessionTemplate属性赋值
  • 如果以上两步不符合判断条件没有执行,则设置MapperFactoryBean的autowireModebyType
  • 其实这段代码中就体现了两种无注解依赖注入方式:

  • 第一种,通过BeanDefinition的PropertyValues,通过这种方式给Bean对象中的某个属性指定值,Spring到时候就会自动调用该属性对应的set方法,并将指定的值传递给set方法,从而完成依赖注入,这种方法不需要在set方法上加注解
  • 第二种,就是设置Bean对象的autowireMode,接下来,我们就来分析一下这种方式
  • 我们可以直接用@Bean的方式来定义autowireMode,比如: image.png

    而UserService中有一个orderService属性和对应的setOrderService方法: image.png

    在这种情况下,我们没有在setOrderService方法上加@Autowired注解,但是这个set方法依然会被Spring执行,就是因为我们在定义userService这个Bean时,将它的autowire(就是前文中的autowireMode)设置为了byType,在Spring中,如果一个Bean的autowireMode为byType,那么:

  • Spring就会先找到这个Bean中的所有set方法
  • 然后遍历每个set方法
  • 然后解析set方法中的参数类型
  • 然后根据方法参数类型从Spring容器中找到对应的Bean对象
  • 然后将找到的Bean对象传递给该参数并执行set方法
  • 从而完成set注入
  • 而如果autowireMode为byName,那么执行流程是类似的,区别在于不是根据参数类型去找Bean对象,而是根据setXxx中的xxx,也就是把xxx作为beanName去Spring容器中找到对应的Bean对象。

    所以,如果我们设置了autowireMode,则表示Spring会自动执行Bean对象中的所有set方法,而不需要我们在set方法上添加@Autowired注解,是不是觉得这个功能还挺好?

    这个功能确实挺强大,或者说,这才是理想中的自动注入,因为不需要程序员再手动的去添加注解了,但就是由于它过于强大,所以我们用得少,因为有时候,一个Bean对象中的set方法,我们并不希望都由Spring来自动执行,有些set方法可能只是程序员在书写代码时自己要用到而已,所以对于程序员来说更习惯用注解,通过注解来控制哪些set方法让Spring自动执行,哪些set方法Spring不用执行。

    所以,利用@Bean中的autowire属性也是一种无注解依赖注入。(不要抬杠说@Bean也是注解,那你可以直接用BeanDefinition来定义Bean,那就真的是无注解了...)

    好了,今天的内容就分享到这,举头望明月,低头看源码,我是爱读源码的大都督,关注我,一起品味源码。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论