目录
项目结构总览
4. 实例演示二:验证 context:exclude-filter 的使用
4.1 context:exclude-filter 的作用
4.3 验证 type="annotation" 的排除方式
4.4 验证 type="assignable" 的排除方式
4.6 验证 use-default-filters="false" 的使用
4.7.1 context:exclude-filter 的使用场景
5. 实例演示三:Bean 的 ID 默认规则与自定义 ID
项目结构---摆烂......摆烂......
spring_ioc_annotation(Spring IOC注解项目)
│
├── src
│ ├── main
│ │ ├── java
│ │ │ └── com
│ │ │ └── atguigu
│ │ │ └── spring
│ │ │ ├── controller
│ │ │ │ └── UserController.java # 控制层组件
│ │ │ ├── service
│ │ │ │ └── impl
│ │ │ │ └── UserServiceImpl.java # 服务层实现
│ │ │ └── dao
│ │ │ └── impl
│ │ │ └── UserDaoImpl.java # 数据访问层实现
│ │ │
│ │ └── resources
│ │ └── spring-ioc-annotation.xml # Spring IOC配置文件
│ │
│ └── test
│ └── java
│ └── com
│ └── atguigu
│ └── spring
│ └── test
│ └── IOCByAnnotationTest.java # 单元测试类
│
├── target # 构建输出目录
│ ├── classes # 编译后的字节码
│ └── test-classes # 测试类编译结果
│
├── pom.xml # Maven项目配置
└── .idea # IDE配置文件(可忽略)
1. 注解和扫描的概念
注解
-
定义:
-
注解是一种标记,用于告诉 Spring 框架如何处理被标记的类或方法。
-
注解本身不会执行任何操作,具体的功能由 Spring 框架实现。
-
-
本质:
-
所有操作都是由 Java 代码完成的,注解只是告诉框架如何执行这些操作。
-
扫描
-
定义:
-
Spring 通过扫描类路径,检测哪些类被注解标记,并根据注解的功能进行处理。
-
-
作用:
-
让 Spring 知道哪些类需要被管理,以及如何管理这些类。
-
2. 标识组件的常用注解
Spring 提供了以下常用注解来标识不同类型的组件:
注解 | 说明 |
---|---|
@Component |
将类标识为普通组件 |
@Controller |
将类标识为控制器组件(用于 MVC) |
@Service |
将类标识为业务层组件 |
@Repository |
将类标识为持久层组件(用于 DAO) |
注解的关系和区别
-
关系:
-
@Controller
、@Service
、@Repository
都是@Component
的派生注解。 -
它们的源码中都包含
@Component
注解。
-
-
区别:
-
功能上没有区别,Spring 对它们的处理方式相同。
-
语义上有区别,用于标识组件的作用层次(控制器、业务层、持久层)。
-
目的是提高代码的可读性和结构严谨性。
-
3. 实例演示一:使用注解和扫描
3.1 配置文件
在 spring-ioc-annotation.xml
中配置组件扫描:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring"></context:component-scan>
</beans>
3.2 标识组件
在类上使用注解标识组件:
-
UserController
类:
package com.atguigu.spring.controller;
import org.springframework.stereotype.Controller;
@Controller
public class UserController {
// 控制器逻辑
}
UserServiceImpl
类:
package com.atguigu.spring.service.impl;
import com.atguigu.spring.service.UserService;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
// 业务逻辑
}
UserDaoImpl
类:
package com.atguigu.spring.dao.impl;
import com.atguigu.spring.dao.UserDao;
import org.springframework.stereotype.Repository;
@Repository
public class UserDaoImpl implements UserDao {
// 数据访问逻辑
}
3.3 测试代码
package com.atguigu.spring.test;
import com.atguigu.spring.controller.UserController;
import com.atguigu.spring.dao.UserDao;
import com.atguigu.spring.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class IOCByAnnotationTest {
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class);
System.out.println(userController);
UserService userService = ioc.getBean(UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class);
System.out.println(userDao);
}
}
3.4 输出结果
com.atguigu.spring.controller.UserController@475e586c
com.atguigu.spring.service.impl.UserServiceImpl@657c8ad9
com.atguigu.spring.dao.impl.UserDaoImpl@436a4e4b
4. 实例演示二:验证 context:exclude-filter
的使用
4.1 context:exclude-filter
的作用
-
功能:用于在组件扫描时排除特定的组件。
-
属性:
-
type
:设置排除扫描的方式。 -
expression
:设置排除的具体内容(注解的全类名或类的全类名)。
-
4.2 type
的取值
-
annotation
:根据注解的类型进行排除。-
expression
需要设置为排除的注解的全类名。
-
-
assignable
:根据类的类型进行排除。-
expression
需要设置为排除的类的全类名。
-
4.3 验证 type="annotation"
的排除方式
配置文件
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-
作用:排除所有带有
@Controller
注解的组件。
测试代码
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class); // 报错
System.out.println(userController);
UserService userService = ioc.getBean(UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class);
System.out.println(userDao);
}
-
测试结果:
-
UserController
无法被找到,抛出NoSuchBeanDefinitionException
异常。 -
UserService
和UserDao
正常加载。
-
-
结论:
type="annotation"
成功排除了带有@Controller
注解的组件。
4.4 验证 type="assignable"
的排除方式
配置文件
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring">
<context:exclude-filter type="assignable" expression="com.atguigu.spring.controller.UserController"/>
</context:component-scan>
-
作用:排除
UserController
类。
测试代码
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class); // 报错
System.out.println(userController);
UserService userService = ioc.getBean(UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class);
System.out.println(userDao);
}
-
测试结果:
-
UserController
无法被找到,抛出NoSuchBeanDefinitionException
异常。 -
UserService
和UserDao
正常加载。
-
-
结论:
type="assignable"
成功排除了UserController
类。
4.5 验证默认扫描行为
配置文件
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring">
<!-- 无排除过滤器 -->
</context:component-scan>
-
作用:扫描
com.atguigu.spring
包下的所有组件。
测试代码
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class);
System.out.println(userController);
UserService userService = ioc.getBean(UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class);
System.out.println(userDao);
}
-
测试结果:
-
UserController
、UserService
和UserDao
均正常加载。
-
-
结论:默认情况下,Spring 会扫描并注册所有带有
@Component
及其派生注解的组件。
4.6 验证 use-default-filters="false"
的使用
配置文件
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-
作用:禁用默认过滤器,仅扫描带有
@Controller
注解的组件。
测试代码
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean(UserController.class);
System.out.println(userController);
UserService userService = ioc.getBean(UserService.class); // 报错
System.out.println(userService);
UserDao userDao = ioc.getBean(UserDao.class); // 报错
System.out.println(userDao);
}
-
测试结果:
-
UserController
正常加载。 -
UserService
和UserDao
无法被找到,抛出NoSuchBeanDefinitionException
异常。
-
-
结论:
use-default-filters="false"
禁用了默认过滤器,仅加载了@Controller
注解的组件。
4.7.实例演示二---总结
4.7.1 context:exclude-filter
的使用场景
-
当需要排除某些特定组件时,可以使用
context:exclude-filter
。 -
通过
type
属性指定排除方式:-
annotation
:根据注解类型排除。 -
assignable
:根据类类型排除。
-
4.7.2 use-default-filters
的作用
-
默认值为
true
,表示启用默认过滤器(扫描所有@Component
及其派生注解的组件)。 -
设置为
false
时,禁用默认过滤器,仅加载通过<context:include-filter>
指定的组件。
5. 实例演示三:Bean 的 ID 默认规则与自定义 ID
5.1 Bean 的 ID 默认规则
-
默认规则:通过注解扫描配置的 Bean,其 ID 默认为类名的小驼峰形式(即首字母小写)。
-
例如:
UserController
类的默认 Bean ID 为userController
。 -
例如:
UserServiceImpl
类的默认 Bean ID 为userServiceImpl
。
-
配置文件
<!-- 扫描组件 -->
<context:component-scan base-package="com.atguigu.spring"></context:component-scan>
测试代码
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean("userController", UserController.class);
System.out.println(userController);
UserService userService = ioc.getBean("userServiceImpl", UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean("userDaoImpl", UserDao.class);
System.out.println(userDao);
}
输出结果
com.atguigu.spring.controller.UserController@143640d5
com.atguigu.spring.service.impl.UserServiceImpl@6295d394
com.atguigu.spring.dao.impl.UserDaoImpl@475e586c
-
结论:Bean 的 ID 默认为类名的小驼峰形式。
5.2 自定义 Bean 的 ID
-
方法:通过在标识组件的注解(如
@Controller
、@Service
等)中设置value
属性,可以自定义 Bean 的 ID。-
例如:
@Controller("controller")
将UserController
的 Bean ID 设置为controller
。
-
修改 UserController
类
@Controller("controller") // 自定义 Bean ID 为 "controller"
package com.atguigu.spring.controller;
import org.springframework.stereotype.Controller;
@Controller("controller") // 自定义 Bean ID 为 "controller"
public class UserController {
}
测试代码(未修改 Bean ID 获取方式)
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean("userController", UserController.class); // 报错
System.out.println(userController);
UserService userService = ioc.getBean("userServiceImpl", UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean("userDaoImpl", UserDao.class);
System.out.println(userDao);
}
测试结果
org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'userController' available
-
原因:
UserController
的 Bean ID 已自定义为controller
,而测试代码中仍尝试通过默认 IDuserController
获取 Bean,导致异常。
修改测试代码(使用自定义 Bean ID)
UserController userController = ioc.getBean("controller", UserController.class); // 使用自定义 ID
@Test
public void test() {
ApplicationContext ioc = new ClassPathXmlApplicationContext("spring-ioc-annotation.xml");
UserController userController = ioc.getBean("controller", UserController.class); // 使用自定义 ID
System.out.println(userController);
UserService userService = ioc.getBean("userServiceImpl", UserService.class);
System.out.println(userService);
UserDao userDao = ioc.getBean("userDaoImpl", UserDao.class);
System.out.println(userDao);
}
输出结果
com.atguigu.spring.controller.UserController@6646153
com.atguigu.spring.service.impl.UserServiceImpl@21507a04
com.atguigu.spring.dao.impl.UserDaoImpl@143640d5
-
结论:通过自定义 Bean ID,可以灵活地指定 Bean 的名称。
5.3 实例演示三---总结
5.3.1 Bean 的 ID 默认规则
-
默认情况下,Spring 会将类名转换为小驼峰形式作为 Bean 的 ID。
-
例如:
UserController
->userController
,UserServiceImpl
->userServiceImpl
。
5.3.2 自定义 Bean 的 ID
-
通过在注解中设置
value
属性,可以自定义 Bean 的 ID。 -
例如:
@Controller("controller")
将 Bean ID 设置为controller
。
5.3.3 注意事项---个屁
-
如果自定义了 Bean 的 ID,获取 Bean 时必须使用自定义的 ID,否则会抛出
NoSuchBeanDefinitionException
异常。
又臭又长又难学,还难理解.......
2025/2/28-18:05:56