Spring IoC容器与Bean管理(五)

简介: 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();
    }
}
相关文章
|
12月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
12月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
904 2
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
354 1
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
487 18
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
XML Java 数据格式
Spring容器的本质
本文主要讨论Spring容器最核心的机制,用最少的代码讲清楚Spring容器的本质。
|
Java Spring 容器
SpringBoot自动配置的原理是什么?
Spring Boot自动配置核心在于@EnableAutoConfiguration注解,它通过@Import导入配置选择器,加载META-INF/spring.factories中定义的自动配置类。这些类根据@Conditional系列注解判断是否生效。但Spring Boot 3.0后已弃用spring.factories,改用新格式的.imports文件进行配置。
1551 0
|
人工智能 Java 测试技术
Spring Boot 集成 JUnit 单元测试
本文介绍了在Spring Boot中使用JUnit 5进行单元测试的常用方法与技巧,包括添加依赖、编写测试类、使用@SpringBootTest参数、自动装配测试模块(如JSON、MVC、WebFlux、JDBC等),以及@MockBean和@SpyBean的应用。内容实用,适合Java开发者参考学习。
1503 0
|
前端开发 Java 数据库
微服务——SpringBoot使用归纳——Spring Boot集成Thymeleaf模板引擎——Thymeleaf 介绍
本课介绍Spring Boot集成Thymeleaf模板引擎。Thymeleaf是一款现代服务器端Java模板引擎,支持Web和独立环境,可实现自然模板开发,便于团队协作。与传统JSP不同,Thymeleaf模板可以直接在浏览器中打开,方便前端人员查看静态原型。通过在HTML标签中添加扩展属性(如`th:text`),Thymeleaf能够在服务运行时动态替换内容,展示数据库中的数据,同时兼容静态页面展示,为开发带来灵活性和便利性。
649 0