Spring IoC容器与Bean管理(五)

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: Spring IoC容器与Bean管理

当然,上面说到spring它会先按name尝试注入,name不存在则按类型注入。那我们试试name不存在时,看看如何运行:

比如我们对Config类的一些代码进行更改,我们把要注入对象的参数的名字从userDao改为udao:


@Bean
    //会按name尝试注入,name不存在则按类型注入
    public UserService userService(UserDao udao){
        UserService userService=new UserService();
        System.out.println("已创建userServices");
        userService.setUserDao(userDao);
        System.out.println("调用setUserDao"+userDao);
        return userService;
    }


然后运行,其实也是不会报错的。因为spring他会在去找容器内相同类型的bean进行注入。

但是,如果在传入要注入的bean的name不正确的情况下,容器中又存在两个注入类型相同的bean,就会报错了,比如我们下面创建两个UserDao的bean。


    @Bean
    public UserDao userDao(){
        UserDao userDao=new UserDao();
        System.out.println("已创建userDao");
        return userDao;
    }
    @Bean
    public UserDao userDao1(){
        UserDao userDao=new UserDao();
        System.out.println("已创建userDao");
        return userDao;
    }
    @Bean
    //会按name尝试注入,name不存在则按类型注入
    public UserService userService(UserDao udao){
        UserService userService=new UserService();
        System.out.println("已创建userServices");
        userService.setUserDao(udao);
        System.out.println("调用setUserDao"+udao);
        return userService;
    }


这时候运行main方法就会报错了。


8e3502db0a124dfeb7a858435942e7d9.png


在这里插入图片描述

它显示发现两个相同类型的Bean,它不知道该注入哪一个bean。

解决这个问题的办法有很多,比如给给其中一个bean添加一个@Primary的注解。使其优先选择被注入。


    @Bean
    public UserDao userDao(){
        UserDao userDao=new UserDao();
        System.out.println("已创建userDao");
        return userDao;
    }
    @Bean
    @Primary
    public UserDao userDao1(){
        UserDao userDao=new UserDao();
        System.out.println("已创建userDao");
        return userDao;
    }
    @Bean
    //会按name尝试注入,name不存在则按类型注入
    public UserService userService(UserDao udao){
        UserService userService=new UserService();
        System.out.println("已创建userServices");
        userService.setUserDao(udao);
        System.out.println("调用setUserDao"+udao);
        return userService;
    }


运行结果如下,这时就不会报错了:


4e5aa48c32224ea0b816b70aa9b4308d.png


下面介绍用@Scope注解配置bean的作用范围为singleton或prototype


    @Bean
    @Scope("prototype")
    public UserController userController(UserService userService){
        UserController userController=new UserController();
        System.out.println("已创建userController");
        userController.setUserService(userService);
        System.out.println("调用setUserService"+userService);
        return userController;
    }


其实Java Config可以和注解配置一起使用,只需要配置@ComponentScan注解,代表扫描包内组件的注解,里面用basePackages来指定要扫描注解的包。


@Configuration
@ComponentScan(basePackages = "com.haiexijun")
public class Config {
    //Java Config利用方法创建对象,将方法返回对象放入容器中,beanId为方法名
    @Bean
    public UserDao userDao(){
    ```````````````
    }


10.Spring与JUnit4整合—Spring Test测试模块


Spring Test 是Spring中用于测试的模块,Spring Test对JUnit单元测试框架有良好的整合。在日常开发中,最常用的一个功能就是与JUnit单元测试进行整合,通过Spring Test这个模块可以在JUnit单元单元测试时自动初始化IoC容器。


Spring与JUnit4的整合过程

1.配置Maven工程依赖spring-test和junit4的依赖


<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-test</artifactId>
  <version>5.3.13</version>
</dependency>


2.利用@RunWith与@ContextConfiguration描述测试用例类。通过@RunWith可以让spring接管JUnit4的控制权,完成IoC的初始化工作,@ContextConfiguration则用于说明在初始化IoC容器过程中到底要加载哪个配置文件。

3.测试用例类从容器获取对象完成测试用例的执行。


下面来演示一下:

创建好userDao类和UserService类后,配置xml文件


package com.haiexijun.ioc.dao;
public class UserDao {
    public void insert(){
        System.out.println("插入一条数据");
    }
}
package com.haiexijun.ioc.service;
import com.haiexijun.ioc.dao.UserDao;
public class UserService {
    private UserDao userDao;
    public void createUser(){
        System.out.println("调用创建用户的业务代码");
        userDao.insert();
    }
    public UserDao getUserDao() {
        return userDao;
    }
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="userDao" class="com.haiexijun.ioc.dao.UserDao">
    </bean>
    <bean id="userService" class="com.haiexijun.ioc.service.UserService">
        <property name="userDao" ref="userDao"/>
    </bean>
</beans>

之后再test包下面创建一个测试用例类SpringTestor:

import com.haiexijun.ioc.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import javax.annotation.*;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
//将Junit4的执行权交给Spring Test,再测试用例执行前自动初始化IoC容器
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:applicationContext.xml"})
public class SpringTestor {
    @Resource
    private UserService userService;
    @Test
    public  void testUserService(){
        userService.createUser();
    }
}
相关文章
|
18天前
|
缓存 Java Spring
实战指南:四种调整 Spring Bean 初始化顺序的方案
本文探讨了如何调整 Spring Boot 中 Bean 的初始化顺序,以满足业务需求。文章通过四种方案进行了详细分析: 1. **方案一 (@Order)**:通过 `@Order` 注解设置 Bean 的初始化顺序,但发现 `@PostConstruct` 会影响顺序。 2. **方案二 (SmartInitializingSingleton)**:在所有单例 Bean 初始化后执行额外的初始化工作,但无法精确控制特定 Bean 的顺序。 3. **方案三 (@DependsOn)**:通过 `@DependsOn` 注解指定 Bean 之间的依赖关系,成功实现顺序控制,但耦合性较高。
实战指南:四种调整 Spring Bean 初始化顺序的方案
|
25天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
1月前
|
Java 测试技术 Windows
咦!Spring容器里为什么没有我需要的Bean?
【10月更文挑战第11天】项目经理给小菜分配了一个紧急需求,小菜迅速搭建了一个SpringBoot项目并完成了开发。然而,启动测试时发现接口404,原因是控制器包不在默认扫描路径下。通过配置`@ComponentScan`的`basePackages`字段,解决了问题。总结:`@SpringBootApplication`默认只扫描当前包下的组件,需要扫描其他包时需配置`@ComponentScan`。
|
17天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
31 0
|
1月前
|
XML Java 数据格式
Spring IOC容器的深度解析及实战应用
【10月更文挑战第14天】在软件工程中,随着系统规模的扩大,对象间的依赖关系变得越来越复杂,这导致了系统的高耦合度,增加了开发和维护的难度。为解决这一问题,Michael Mattson在1996年提出了IOC(Inversion of Control,控制反转)理论,旨在降低对象间的耦合度,提高系统的灵活性和可维护性。Spring框架正是基于这一理论,通过IOC容器实现了对象间的依赖注入和生命周期管理。
71 0
|
1月前
|
XML Java 数据格式
Spring的IOC和AOP
Spring的IOC和AOP
48 0
|
13天前
|
Kubernetes Cloud Native Docker
云原生时代的容器化实践:Docker和Kubernetes入门
【10月更文挑战第37天】在数字化转型的浪潮中,云原生技术成为企业提升敏捷性和效率的关键。本篇文章将引导读者了解如何利用Docker进行容器化打包及部署,以及Kubernetes集群管理的基础操作,帮助初学者快速入门云原生的世界。通过实际案例分析,我们将深入探讨这些技术在现代IT架构中的应用与影响。
55 2
|
3天前
|
Kubernetes Linux 开发者
深入探索容器化技术——Docker 的实战应用
深入探索容器化技术——Docker 的实战应用
23 5
|
6天前
|
运维 Cloud Native 云计算
云原生之旅:Docker容器化实战
本文将带你走进云原生的世界,深入理解Docker技术如何改变应用部署与运维。我们将通过实际案例,展示如何利用Docker简化开发流程,提升应用的可移植性和伸缩性。文章不仅介绍基础概念,还提供操作指南和最佳实践,帮助你快速上手Docker,开启云原生的第一步。
|
10天前
|
机器学习/深度学习 数据采集 Docker
Docker容器化实战:构建并部署一个简单的Web应用
Docker容器化实战:构建并部署一个简单的Web应用
下一篇
无影云桌面