Springs 依赖注入,组装对象之间的依赖关系(2)

简介: 整理了spring容器注册bean的实现方式,本文将整理spring注入bean的实现方式,多数文章按照setter和构造器注入的纬度来介绍,本文将按照如何采用setter和构造器的纬度来整理,即xml配置注入、xml配置自动装配、注解自动装配三种方式。

整理了spring容器注册bean的实现方式,本文将整理spring注入bean的实现方式,多数文章按照setter和构造器注入的纬度来介绍,本文将按照如何采用setter和构造器的纬度来整理,即xml配置注入、xml配置自动装配、注解自动装配三种方式。

xml配置注入,手动装配,提供setter方法或者constructor构造函数

需提供setter方法方式

spring的xml配置文件:

 <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl">
        <!-- 配置注入属性 -->
        <property name="userDao" ref="userDao"></property>
    </bean>

UserServiceImpl:

//声明UserDao属性,名字与xml中property的name名称不具有关联性,比如可以叫userDaoAlias
private UserDao userDao;
//setter方法,其中setXxxx的Xxxx要与xml文件中property标签中name属性值一致,首字母大写,具有关联性
public void setUserDao(UserDao userDao) {
        System.out.println("setUserDao注入");
        this.userDao = userDao;
    }

需提供构造器方式

spring的xml配置文件:

 <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl">
        <!-- 配置注入属性 -->
        <constructor-arg name="userDao" ref="userDao"></constructor-arg>
    </bean>

UserServiceImpl:
声明UserDao属性,属性名与标签中name属性值无关

 private UserDao userDao;
    //参数名与<constructor-arg>标签中name属性值具有关联性
    public UserServiceImpl(UserDao userDao){
        System.out.println("构造器UserServiceImpl注入");
        this.userDao = userDao;
    }

xml配置注入,自动装配,提供setter方法或者constructor构造函数

spring提供了三种自动装配的方式,实现的方式为在bean标签中添加autowire属性或者在beans中添加全局的default-autowire属性,属性值如下:

byName:把Bean的属性具有相同名字的的其他Bean自动装配到Bean的对应属性中

spring的xml配置文件:

  <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>
    <!-- 注册bean并自动装配所有属性bean -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl" autowire="byName"></bean>

UserServiceImpl:
与前面的1、需提供setter方法方式相同,需要setter方法

    //声明UserDao属性不具有关联性
    private UserDao userDao;

    //setter方法,其中setXxxx的Xxxx要与xml文件中property标签中name属性值一致,首字母大写,具有关联性
    public void setUserDao(UserDao userDao) {
        System.out.println("自动装配byName-setUserDao注入");
        this.userDao = userDao;
    }

byType:把与Bean的属性具有相同类型的的其他Bean 自动装配Bean的对应属性当中,如果存在多个该类型bean,那么抛出异常,并指出不能使用byType进行自动装配;如果没有找到相匹配的bean,则什么事都不发生

spring的xml配置文件:

    <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <!-- 注册bean并自动装配所有属性bean -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl" autowire="byType"></bean>

UserServiceImpl:

byType方式同样依赖于setter方法,但与setter方法名不再具有关联性,而是与setter的参数类型具有关联性,setter参数类型必须是所注入bean的类型或父类型

    //声明UserDao属性名不具有关联性
    private UserDao userDao;

    //setter方法的参数类型必须是所注入bean的类型或父类型
    public void setUserDao(UserDao userDao) {
        System.out.println("自动装配byType-setUserDao注入");
        this.userDao = userDao;
    }

注意:在应用上下文(spring容器)中,如果有多个bean的类型与该bean的自动装配属性相匹配,那么就会出错,因为byType方式只允许匹配一个类型相同的Bean。

spring提供了两种选择,可以设置一个首选bean,或者排除一些bean。

2.1)、设置首选bean:
元素的primary属性代表是否是首选bean,如果标注为true,那么该bean将成为首选bean,但是spring默认每个bean的primary属性都是true,所以如果需要设置首选bean需要将那些非首选bean的primary属性标注为false。

spring的xml配置文件:

 <!-- 将UserDaoImpl注册为非首选bean -->
    <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl" primary="false"></bean>

    <!-- 将UserDaoImpl2注册为首选bean -->
    <bean id="userDao2" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl2" primary="true"></bean>

    <!-- 设置自动装配方式为byType -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl" autowire="byType"></bean>

UserServiceImpl:代码不变,UserDaoImpl2的实例save方法被执行。

2.2)、排除一些bean:
在自动装配的过程当中,想排除某些bean的时候,可是使用把autowire-candidate属性设置为false。

spring的xml配置文件:

 <!-- 注册bean -->
    <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <!-- 注册bean,但是将该bean作为属性时被自动装配设置为false,因此该bean作为属性不会被自动装配 -->
    <bean id="userDao2" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl2" autowire-candidate="false"></bean>

    <!-- 设置自动装配方式为byType -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl" autowire="byType"></bean>

UserServiceImpl:代码不变,UserDaoImpl的实例save方法被执行。

3、constructor:把与Bean的构造器入参具有相同类型的其他Bean自动装配到构造器的对应入参中,如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常

spring的xml配置文件:

 <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <!-- 注册bean并自动装配所有属性bean -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl" autowire="constructor"></bean>

UserServiceImpl:
private UserDao userDao;

    //constructor自动装配依赖于构造器参数类型,与名称无关,类型必须是所注入bean的类型或父类型
    public UserServiceImpl(UserDao userDao){
        System.out.println("自动装配构造器UserServiceImpl注入");
        this.userDao = userDao;
    }

4、补充:设置全局的默认自动装配

如果在一个配置文件中,所有的装配都使用同一种自动配置方式的话, 要在每个bean声明的时候都加上一个autowire属性比较麻烦,为了避免这样的重复操作,可以使用默认自动装配。

使用默认自动装配的方法是在元素中添加一个default-autowire属性,但如果bean上直接设置autowire属性会覆盖掉默认自动装配的配置。

default-autowire属性值与上面单独bean设置autowire属性值一样,都是三个,byName、byType、constructor。

spring的xml配置文件:

<beans ...
  default-autowire="byName">
</beans>

UserServiceImpl:参照上面单独配置bean的形式

注解自动装配,可以不用提供setter方法或者constructor构造函数

在使用注解装配之前,首先要开启注解装配的方式,那就是在配置文件中加上下面这句话,也可以使用标签。

使用@Autowired注解,可以用在属性、setter方法、constructor构造方法上,实现自动装配。

spring的xml配置文件:

 <!-- 开启注解配置 -->
    <context:annotation-config></context:annotation-config>

    <!-- 注册bean -->
    <bean id="userDao" class="com.jsun.test.springDemo.ioc.User.UserDaoImpl"></bean>

    <!-- 注册bean -->
    <bean id="userService" class="com.jsun.test.springDemo.ioc.User.UserServiceImpl"></bean>

UserServiceImpl:

1、注解在setter方法上:

  private UserDao userDao;

    //添加注解,匹配注入与参数类型有关,与参数名称、setter方法名称、成员变量属性名称无关
    @Autowired
    public void setUserDao(UserDao userDao) {
        System.out.println("注解自动装配setUserDao注入");
        this.userDao = userDao;
    }

2、constructor构造方法上:

 private UserDao userDao;

    //添加注解,匹配注入与参数类型有关,与参数名称、成员变量属性名称无关
    @Autowired
    public UserServiceImpl(UserDao userDao){
        System.out.println("注解自动装配构造器UserServiceImpl注入");
        this.userDao = userDao;
    }

3、声明的属性上:

添加注解,先按照属性名称匹配注入,如果未找到则按照属性类型匹配注入

@Autowired
private UserDao userDao;

4、补充:@Value注解基本类型数据或动态装配数据

@Value("我就是注入strValue属性的值")
private String strValue;

使用表达式来动态的计算并装配属性的值,比如使用spel表达式从系统属性中取得一个值

@Value("#{systemProperties.myFavoriteSong}")
private String strValue;

也可以像使用EL表达式一样,获取spring上下文中加载的*.properties资源文件数据:

@Value("${jdbc.url}")
private String url;

作者:glowd
原文:https://blog.csdn.net/zengqiang1/article/details/54601044
版权声明:本文为博主原创文章,转载请附上博文链接!

相关文章
|
4天前
|
云安全 人工智能 安全
AI被攻击怎么办?
阿里云提供 AI 全栈安全能力,其中对网络攻击的主动识别、智能阻断与快速响应构成其核心防线,依托原生安全防护为客户筑牢免疫屏障。
|
14天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
8天前
|
安全 Java Android开发
深度解析 Android 崩溃捕获原理及从崩溃到归因的闭环实践
崩溃堆栈全是 a.b.c?Native 错误查不到行号?本文详解 Android 崩溃采集全链路原理,教你如何把“天书”变“说明书”。RUM SDK 已支持一键接入。
550 206
|
3天前
|
编解码 Linux 数据安全/隐私保护
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
教程分享免费视频压缩软件,免费视频压缩,视频压缩免费,附压缩方法及学习教程
225 138
|
存储 人工智能 监控
从代码生成到自主决策:打造一个Coding驱动的“自我编程”Agent
本文介绍了一种基于LLM的“自我编程”Agent系统,通过代码驱动实现复杂逻辑。该Agent以Python为执行引擎,结合Py4j实现Java与Python交互,支持多工具调用、记忆分层与上下文工程,具备感知、认知、表达、自我评估等能力模块,目标是打造可进化的“1.5线”智能助手。
755 56
|
6天前
|
人工智能 移动开发 自然语言处理
2025最新HTML静态网页制作工具推荐:10款免费在线生成器小白也能5分钟上手
晓猛团队精选2025年10款真正免费、无需编程的在线HTML建站工具,涵盖AI生成、拖拽编辑、设计稿转代码等多种类型,均支持浏览器直接使用、快速出图与文件导出,特别适合零基础用户快速搭建个人网站、落地页或企业官网。
1082 157
|
4天前
|
存储 Linux iOS开发
最新学习教程,电脑剪贴板不够用!这几个方法教你更多复制粘贴超高效方法,并附上几个扩展工具供你学习
最新学习教程,电脑剪贴板不够用!这几个方法教你更多复制粘贴超高效方法,并附上几个扩展工具供你学习
218 136