一文打通基于注解管理Bean(一)

简介: 一文打通基于注解管理Bean

f8854864de5e426982d91ed0904b08bc.png

从 Java 5 开始,Java 增加了对注解(Annotation)的支持,它是代码中的一种特殊标记,可以在编译、类加载和运行时被读取,执行相应的处理。开发人员可以通过注解在不改变原有代码和逻辑的情况下,在源代码中嵌入补充信息。

Spring 从 2.5 版本开始提供了对注解技术的全面支持,我们可以使用注解来实现自动装配,简化 Spring 的 XML 配置。

Spring 通过注解实现自动装配的步骤如下:

  1. 引入依赖
  2. 开启组件扫描
  3. 使用注解定义 Bean
  4. 依赖注入

开启组件扫描

Spring 默认不使用注解装配 Bean,因此我们需要在 Spring 的 XML 配置中,通过 context:component-scan 元素开启 Spring Beans的自动扫描功能。开启此功能后,Spring 会自动从扫描指定的包(base-package 属性设置)及其子包下的所有类,如果类上使用了 @Component 注解,就将该类装配到容器中。

1. <?xml version="1.0" encoding="UTF-8"?>
2. <beans xmlns="http://www.springframework.org/schema/beans"
3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4. xmlns:context="http://www.springframework.org/schema/context"
5. xsi:schemaLocation="http://www.springframework.org/schema/beans
6.     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
7.     http://www.springframework.org/schema/context
8.             http://www.springframework.org/schema/context/spring-context.xsd">
9. <!--开启组件扫描功能-->
10. <context:component-scan base-package="com.atguigu.spring6"></context:component-scan>
11. </beans>

注意:在使用 context:component-scan 元素开启自动扫描功能前,首先需要在 XML 配置的一级标签 <beans> 中添加 context 相关的约束。

情况一:最基本的扫描方式  

1. <context:component-scan base-package="com.atguigu.spring6">
2. </context:component-scan>

情况二:指定要排除的组件

1. <context:component-scan base-package="com.atguigu.spring6">
2. <!-- context:exclude-filter标签:指定排除规则 -->
3. <!-- 
4.      type:设置排除或包含的依据
5.    type="annotation",根据注解排除,expression中设置要排除的注解的全类名
6.    type="assignable",根据类型排除,expression中设置要排除的类型的全类名
7.  -->
8. <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
9. <!--<context:exclude-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
10. </context:component-scan>

情况三:仅扫描指定组件

1. <context:component-scan base-package="com.atguigu" use-default-filters="false">
2. <!-- context:include-filter标签:指定在原有扫描规则的基础上追加的规则 -->
3. <!-- use-default-filters属性:取值false表示关闭默认扫描规则 -->
4. <!-- 此时必须设置use-default-filters="false",因为默认规则即扫描指定包下所有类 -->
5. <!-- 
6.      type:设置排除或包含的依据
7.    type="annotation",根据注解排除,expression中设置要排除的注解的全类名
8.    type="assignable",根据类型排除,expression中设置要排除的类型的全类名
9.  -->
10. <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
11.   <!--<context:include-filter type="assignable" expression="com.atguigu.spring6.controller.UserController"/>-->
12. </context:component-scan>

使用注解定义 Bean

Spring 提供了以下多个注解,这些注解可以直接标注在 Java 类上,将它们定义成 Spring Bean。

注解 说明
@Component 该注解用于描述 Spring 中的 Bean,它是一个泛化的概念,仅仅表示容器中的一个组件(Bean),并且可以作用在应用的任何层次,例如 Service 层、Dao 层等。 使用时只需将该注解标注在相应类上即可。
@Repository 该注解用于将数据访问层(Dao 层)的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Service 该注解通常作用在业务层(Service 层),用于将业务层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。
@Controller 该注解通常作用在控制层(如SpringMVC 的 Controller),用于将控制层的类标识为 Spring 中的 Bean,其功能与 @Component 相同。

@Autowired注入

单独使用@Autowired注解,默认根据类型装配。【默认是byType】

源码:

1. @Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
2. @Retention(RetentionPolicy.RUNTIME)
3. @Documented
4. public @interface Autowired {
5. boolean required() default true;
6. }

源码中有两处需要注意:

  • 第一处:该注解可以标注在哪里?
  1. 构造方法上
  2. 注解上
  3. 属性上
  4. 形参上
  5. 方法上
  • 第二处:该注解有一个required属性,默认值是true,表示在注入的时候要求被注入的Bean必须是存在的,如果不存在则报错。如果required属性设置为false,表示注入的Bean存在或者不存在都没关系,存在的话就注入,不存在的话,也不报错。

①场景一:属性注入

创建UserDao接口

1. public interface UserDao {
2. 
3. public void print();
4. }

创建UserDaoImpl实现

1. @Repository
2. public class UserDaoImpl implements UserDao {
3. 
4. @Override
5. public void print() {
6.         System.out.println("Dao层执行结束");
7.     }
8. }

创建UserService接口

1. public interface UserService {
2. 
3. public void out();
4. }

创建UserServiceImpl实现类

1. @Service
2. public class UserServiceImpl implements UserService {
3. 
4. @Autowired
5. private UserDao userDao;
6. 
7. @Override
8. public void out() {
9.         userDao.print();
10.         System.out.println("Service层执行结束");
11.     }
12. }

创建UserController类

1. @Controller
2. public class UserController {
3. 
4. @Autowired
5. private UserService userService;
6. 
7. public void out() {
8.         userService.out();
9.         System.out.println("Controller层执行结束。");
10.     }
11. 
12. }

测试

1. public class UserTest {
2. 
3. private Logger logger = LoggerFactory.getLogger(UserTest.class);
4. 
5. @Test
6. public void testAnnotation(){
7. ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
8. UserController userController = context.getBean("userController", UserController.class);
9.         userController.out();
10.         logger.info("执行成功");
11.     }
12. 
13. }

以上构造方法和setter方法都没有提供,经过测试,仍然可以注入成功。

②场景二:set注入

修改UserServiceImpl类

1. @Service
2. public class UserServiceImpl implements UserService {
3. 
4. private UserDao userDao;
5. @Autowired
6. public void setUserDao(UserDao userDao) {
7. this.userDao = userDao;
8.     }
9. 
10. @Override
11. public void out() {
12.         userDao.print();
13.         System.out.println("Service层执行结束");
14.     }
15. }

修改UserController类

1. @Controller
2. public class UserController {
3. 
4. private UserService userService;
5. 
6. @Autowired
7. public void setUserService(UserService userService) {
8. this.userService = userService;
9.     }
10. 
11. public void out() {
12.         userService.out();
13.         System.out.println("Controller层执行结束。");
14.     }
15. 
16. }

测试:成功调用


相关文章
|
存储 缓存 监控
|
存储 算法 量子技术
计算机为什么采用二进制
计算机为什么采用二进制
1853 0
|
Android开发 UED
【Android 学习笔记】之 Material design
版权声明:本文为博主原创文章,转载请注明出处http://blog.csdn.net/u013132758。 https://blog.csdn.net/u013132758/article/details/50923501 最近写一款APP,写完后感觉就是UI太烂、、太烂、太烂。
1129 0
|
Web App开发 移动开发 HTML5
HTML5 网站大观:15个清爽简约风格的 HTML5 网站作品
本期的 HTML5 网站大观与大家分享15个精美的 HTML5 清爽简约风格网站。HTML5 是现在Web开发领域的热点,越来越多的开发人员开始使用 HTML5 来开发交互性强、效果出众的Web应用和游戏。
835 0
|
8天前
|
人工智能 运维 安全
|
6天前
|
人工智能 异构计算
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
敬请锁定《C位面对面》,洞察通用计算如何在AI时代持续赋能企业创新,助力业务发展!
|
7天前
|
机器学习/深度学习 人工智能 自然语言处理
B站开源IndexTTS2,用极致表现力颠覆听觉体验
在语音合成技术不断演进的背景下,早期版本的IndexTTS虽然在多场景应用中展现出良好的表现,但在情感表达的细腻度与时长控制的精准性方面仍存在提升空间。为了解决这些问题,并进一步推动零样本语音合成在实际场景中的落地能力,B站语音团队对模型架构与训练策略进行了深度优化,推出了全新一代语音合成模型——IndexTTS2 。
654 23
|
7天前
|
人工智能 测试技术 API
智能体(AI Agent)搭建全攻略:从概念到实践的终极指南
在人工智能浪潮中,智能体(AI Agent)正成为变革性技术。它们具备自主决策、环境感知、任务执行等能力,广泛应用于日常任务与商业流程。本文详解智能体概念、架构及七步搭建指南,助你打造专属智能体,迎接智能自动化新时代。