Spring IOC容器的理解(六)

简介: Spring IOC容器的理解(六)

第四节 基于注解管理bean
第一个实验 [重要]标记与扫描

第二个实验 [重要]自动装配

第三个实验 完全注解开发

第四个实验 整合junit4

第一个实验 [重要]标记与扫描

1、注解的作用①注解②扫描

2、新建Module

3、创建Spring配置文件

4、创建一组组件类

①使用@Component注解标记的普通组件

②使用@Controller注解标记的控制器组件

③使用@Service注解标记的业务逻辑组件

④使用@Repository注解标记的持久化层组件

5、四个典型注解没有本质区别

6、扫描

①情况一:最基本的扫描方式[常用]

②情况二:指定匹配模式

③情况三:指定要排除的组件

④情况四:仅扫描指定组件

7、组件的beanName

①默认情况

②使用value属性指定

第一个实验 [重要]标记与扫描
1、注解的作用
①注解
和 XML 配置文件一样,注解本身并不能执行,注解本身仅仅只是做一个标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作。

本质上:所有一切的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行。

举例:元旦联欢会要布置教室,蓝色的地方贴上元旦快乐四个字,红色的地方贴上拉花,黄色的地方贴上气球。

班长做了所有标记,同学们来完成具体工作。墙上的标记相当于我们在代码中使用的注解,后面同学们做的工作,相当于框架的具体操作。

②扫描
Spring 为了知道程序员在哪些地方标记了什么注解,就需要通过扫描的方式,来进行检测。然后根据注解进行后续操作。

2、新建Module

<!-- 基于Maven依赖传递性,导入spring-context依赖即可导入当前所需所有jar包 -->
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.3.1</version>
</dependency>

<!-- junit测试 -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>


3、创建Spring配置文件

4、创建一组组件类
①使用@Component注解标记的普通组件
package com.atguigu.ioc.component;

import org.springframework.stereotype.Component;

@Component
public class CommonComponent {
}
②使用@Controller注解标记的控制器组件
这个组件就是我们在三层架构中表述层里面,使用的控制器。以前是Servlet,以后我们将会使用Controller来代替Servlet。

package com.atguigu.ioc.component;

import org.springframework.stereotype.Controller;

@Controller
public class SoldierController {
}
③使用@Service注解标记的业务逻辑组件
这个组件就是我们在三层架构中使用的业务逻辑组件。

package com.atguigu.ioc.component;

import org.springframework.stereotype.Service;

@Service
public class SoldierService {

}
④使用@Repository注解标记的持久化层组件
这个组件就是我们以前用的Dao类,但是以后我们整合了Mybatis,这里就变成了Mapper接口,而Mapper接口是由Mybatis和Spring的整合包负责扫描的。

由于Mybatis整合包想要把Mapper接口背后的代理类加入Spring的IOC容器需要结合Mybatis对Mapper配置文件的解析,所以这个事情是Mybatis和Spring的整合包来完成,将来由Mybatis负责扫描,也不使用@Repository注解。

package com.atguigu.ioc.component;

import org.springframework.stereotype.Repository;

@Repository
public class SoldierDao {
}
5、四个典型注解没有本质区别

通过查看源码我们得知,@Controller、@Service、@Repository这三个注解只是在@Component注解的基础上起了三个新的名字。

对于Spring使用IOC容器管理这些组件来说没有区别。所以@Controller、@Service、@Repository这三个注解只是给开发人员看的,让我们能够便于分辨组件的作用。

注意:虽然它们本质上一样,但是为了代码的可读性,为了程序结构严谨我们肯定不能随便胡乱标记。

6、扫描
①情况一:最基本的扫描方式[常用]

<context:component-scan base-package="com.atguigu.ioc.component"/>
从IOC容器中获取bean

@Test
public void testAnnotationcScanBean() {

CommonComponent commonComponent = iocContainer.getBean(CommonComponent.class);

SoldierController soldierController = iocContainer.getBean(SoldierController.class);

SoldierService soldierService = iocContainer.getBean(SoldierService.class);

SoldierDao soldierDao = iocContainer.getBean(SoldierDao.class);

System.out.println("commonComponent = " + commonComponent);
System.out.println("soldierController = " + soldierController);
System.out.println("soldierService = " + soldierService);
System.out.println("soldierDao = " + soldierDao);

}

②情况二:指定匹配模式

<context:component-scan
        base-package="com.atguigu.ioc.component"
        resource-pattern="Soldier*.class"/>

③情况三:指定要排除的组件
或者也可以说指定不扫描的组件

<context:component-scan base-package="com.atguigu.ioc.component">


<!-- context:exclude-filter标签:指定排除规则 -->
<!-- type属性:指定根据什么来进行排除,annotation取值表示根据注解来排除 -->
<!-- expression属性:指定排除规则的表达式,对于注解来说指定全类名即可 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

</context:component-scan>
④情况四:仅扫描指定组件

<context:component-scan base-package="com.atguigu.ioc.component" use-default-filters="false">


<!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>

</context:component-scan>
7、组件的beanName
在我们使用XML方式管理bean的时候,每个bean都有一个唯一标识,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识。

①默认情况
类名首字母小写就是bean的id。例如:SoldierController类对应的bean的id就是soldierController。

②使用value属性指定
@Controller(value = "tianDog")
public class SoldierController {
}
当注解中只设置一个属性时,value属性的属性名可以省略:

@Service("smallDog")
public class SoldierService {

}
第二个实验 [重要]自动装配

1、设定情景

①在SoldierController中声明方法

②在SoldierService中声明方法

③在SoldierDao中声明方法

2、自动装配的实现

①前提

②@Autowired注解

[1]给Controller装配Service

[2]给Service装配Dao

3、@Autowired注解其他细节

①标记在其他位置

[1]构造器

[2]setXxx()方法

②@Autowired工作流程

③佛系装配

第二个实验 [重要]自动装配
1、设定情景
SoldierController需要SoldierService
SoldierService需要SoldierDao
同时在各个组件中声明要调用的方法。

①在SoldierController中声明方法
package com.atguigu.ioc.component;

import org.springframework.stereotype.Controller;

@Controller(value = "tianDog")
public class SoldierController {

private SoldierService soldierService;

public void getMessage() {
    soldierService.getMessage();
}


}
②在SoldierService中声明方法
@Service("smallDog")
public class SoldierService {

private SoldierDao soldierDao;

public void getMessage() {
    soldierDao.getMessage();
}

}
③在SoldierDao中声明方法
@Repository
public class SoldierDao {

public void getMessage() {
    System.out.println("I am a soldier");
}


}
2、自动装配的实现
①前提
参与自动装配的组件(需要装配别人、被别人装配)全部都必须在IOC容器中。

②@Autowired注解
在成员变量上直接标记@Autowired注解即可,不需要提供setXxx()方法。以后我们在项目中的正式用法就是这样。

[1]给Controller装配Service

@Controller(value = "tianDog")
public class SoldierController {


@Autowired
private SoldierService soldierService;

public void getMessage() {
    soldierService.getMessage();
}

}
[2]给Service装配Dao

@Service("smallDog")
public class SoldierService {


@Autowired
private SoldierDao soldierDao;

public void getMessage() {
    soldierDao.getMessage();
}

}
3、@Autowired注解其他细节
①标记在其他位置
[1]构造器

@Controller(value = "tianDog")
public class SoldierController {


private SoldierService soldierService;

@Autowired
public SoldierController(SoldierService soldierService) {
    this.soldierService = soldierService;
}
……

[2]setXxx()方法

@Controller(value = "tianDog")
public class SoldierController {

private SoldierService soldierService;

@Autowired
public void setSoldierService(SoldierService soldierService) {
    this.soldierService = soldierService;
}
……

②@Autowired工作流程

首先根据所需要的组件类型到IOC容器中查找

能够找到唯一的bean:直接执行装配

如果完全找不到匹配这个类型的bean:装配失败

和所需类型匹配的bean不止一个

没有@Qualifier注解:根据@Autowired标记位置成员变量的变量名作为bean的id进行匹配

能够找到:执行装配
找不到:装配失败
使用@Qualifier注解:根据@Qualifier注解中指定的名称作为bean的id进行匹配

能够找到:执行装配
找不到:装配失败
@Controller(value = "tianDog")
public class SoldierController {


@Autowired
@Qualifier(value = "maomiService222")
// 根据面向接口编程思想,使用接口类型引入Service组件
private ISoldierService soldierService;

③佛系装配
给@Autowired注解设置required = false属性表示:能装就装,装不上就不装。但是实际开发时,基本上所有需要装配组件的地方都是必须装配的,用不上这个属性。

@Controller(value = "tianDog")
public class SoldierController {

// 给@Autowired注解设置required = false属性表示:能装就装,装不上就不装
@Autowired(required = false)
private ISoldierService soldierService;
相关文章
|
2月前
|
XML Java 测试技术
《深入理解Spring》:IoC容器核心原理与实战
Spring IoC通过控制反转与依赖注入实现对象间的解耦,由容器统一管理Bean的生命周期与依赖关系。支持XML、注解和Java配置三种方式,结合作用域、条件化配置与循环依赖处理等机制,提升应用的可维护性与可测试性,是现代Java开发的核心基石。
|
2月前
|
XML Java 应用服务中间件
【SpringBoot(一)】Spring的认知、容器功能讲解与自动装配原理的入门,带你熟悉Springboot中基本的注解使用
SpringBoot专栏开篇第一章,讲述认识SpringBoot、Bean容器功能的讲解、自动装配原理的入门,还有其他常用的Springboot注解!如果想要了解SpringBoot,那么就进来看看吧!
441 2
|
6月前
|
XML 人工智能 Java
Spring IOC 到底是什么?
IOC(控制反转)是一种设计思想,主要用于解耦代码,简化依赖管理。其核心是将对象的创建和管理交给容器处理,而非由程序直接硬编码实现。通过IOC,开发者无需手动new对象,而是由框架负责实例化、装配和管理依赖对象。常见应用如Spring框架中的BeanFactory和ApplicationContext,它们实现了依赖注入和动态管理功能,提升了代码的灵活性与可维护性。
197 1
|
XML Java 数据格式
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
京东一面:spring ioc容器本质是什么? ioc容器启动的步骤有哪些?
|
7月前
|
XML Java 数据格式
Spring IoC容器的设计与实现
Spring 是一个功能强大且模块化的 Java 开发框架,其核心架构围绕 IoC 容器、AOP、数据访问与集成、Web 层支持等展开。其中,`BeanFactory` 和 `ApplicationContext` 是 Spring 容器的核心组件,分别定位为基础容器和高级容器,前者提供轻量级的 Bean 管理,后者扩展了事件发布、国际化等功能。
|
9月前
|
Java 容器 Spring
什么是Spring IOC 和DI ?
IOC : 控制翻转 , 它把传统上由程序代码直接操控的对象的调用权交给容 器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转 移,从程序代码本身转移到了外部容器。 DI : 依赖注入,在我们创建对象的过程中,把对象依赖的属性注入到我们的类中。
|
XML Java 数据格式
Spring IoC容器初始化过程(xml形式)
Spring IoC容器初始化过程(xml形式)
242 0
|
XML Java 数据格式
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
Spring5源码(15)-IoC容器启动过程简析及XmlBeanFactory初始化
150 1
|
XML Java 数据格式
Spring源码阅读-IOC容器初始化过程
Spring IOC容器的初始化过程:Resource定位,BeanDefinition载入,向IOC容器注册BeanDefinition。整个过程由refresh()方法触发,三个过程由不同的模块完成,使用户更加灵活的对这三个过程剪裁和扩展。
382 0
|
XML 设计模式 Java
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程
246 0
「推荐收藏!」【Spring源码探究】(一)IOC容器初始化🏅彻底让你明白运行原理和源码流程