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

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

③场景三:构造方法注入

修改UserServiceImpl类

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

修改UserController类

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

测试:成功调用

④场景四:形参上注入

修改UserServiceImpl类

1. @Service
2. public class UserServiceImpl implements UserService {
3. 
4. private UserDao userDao;
5. 
6. public UserServiceImpl(@Autowired 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. public UserController(@Autowired UserService userService) {
7. this.userService = userService;
8.     }
9. 
10. public void out() {
11.         userService.out();
12.         System.out.println("Controller层执行结束。");
13.     }
14. 
15. }

测试:成功调用

⑤场景五:只有一个构造函数,无注解

修改UserServiceImpl类

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

测试通过

当有参数的构造方法只有一个时,@Autowired注解可以省略。

说明:有多个构造方法时呢?大家可以测试(再添加一个无参构造函数),测试报错

⑥场景六:@Autowired注解和@Qualifier注解联合+

添加dao层实现

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

测试:测试异常

错误信息中说:不能装配,UserDao这个Bean的数量等于2

怎么解决这个问题呢?**当然要byName,根据名称进行装配了。**

修改UserServiceImpl类

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

总结

  • @Autowired注解可以出现在:属性上、构造方法上、构造方法的参数上、setter方法上。
  • 当带参数的构造方法只有一个,@Autowired注解可以省略。()
  • @Autowired注解默认根据类型注入。如果要根据名称注入的话,需要配合@Qualifier注解一起使用。

@Resource注入

@Resource注解也可以完成属性注入。那它和@Autowired注解有什么区别?

  • @Resource注解是JDK扩展包中的,也就是说属于JDK的一部分。所以该注解是标准注解,更加具有通用性。(JSR-250标准中制定的注解类型。JSR是Java规范提案。)
  • @Autowired注解是Spring框架自己的。
  • @Resource注解默认根据名称装配byName,未指定name时,使用属性名作为name。通过name找不到的话会自动启动通过类型byType装配。
  • @Autowired注解默认根据类型装配byType,如果想根据名称装配,需要配合@Qualifier注解一起用。
  • @Resource注解用在属性上、setter方法上。
  • @Autowired注解用在属性上、setter方法上、构造方法上、构造方法参数上。

@Resource注解属于JDK扩展包,所以不在JDK当中,需要额外引入以下依赖:【如果是JDK8的话不需要额外引入依赖。高于JDK11或低于JDK8需要引入以下依赖。

1. <dependency>
2.     <groupId>jakarta.annotation</groupId>
3.     <artifactId>jakarta.annotation-api</artifactId>
4.     <version>2.1.1</version>
5. </dependency>

①场景一:根据name注入

修改UserDaoImpl类

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

修改UserServiceImpl类

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

②场景二:name未知注入

修改UserDaoImpl类

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

修改UserServiceImpl类

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

测试通过

当@Resource注解使用时没有指定name的时候,还是根据name进行查找,这个name是属性名。

③场景三 其他情况

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

测试异常

根据异常信息得知:显然当通过name找不到的时候,自然会启动byType进行注入,以上的错误是因为UserDao接口下有两个实现类导致的。所以根据类型注入就会报错。

@Resource的set注入可以自行测试

总结

@Resource注解:默认byName注入,没有指定name时把属性名当做name,根据name找不到时,才会byType注入。byType注入时,某种类型的Bean只能有一个

spring全注解开发

全注解开发就是不再使用spring配置文件了,写一个配置类来代替配置文件。

1. @Configuration
2. //@ComponentScan({"com.atguigu.spring6.controller", "com.atguigu.spring6.service","com.atguigu.spring6.dao"})
3. @ComponentScan("com.atguigu.spring6")
4. public class Spring6Config {
5. }

测试类

1. @Test
2. public void testAllAnnotation(){
3. ApplicationContext context = new AnnotationConfigApplicationContext(Spring6Config.class);
4. UserController userController = context.getBean("userController", UserController.class);
5.     userController.out();
6.     logger.info("执行成功");
7. }


相关文章
|
Kubernetes 关系型数据库 MySQL
Docker Compose入门:打造多容器应用的完美舞台
Docker Compose 是一个强大的工具,它允许开发者通过简单的 YAML 文件定义和管理多容器的应用。本文将深入讨论 Docker Compose 的基本概念、常用命令以及高级应用场景,并通过更为丰富和实际的示例代码,助您轻松掌握如何通过 Docker Compose 打造复杂而高效的多容器应用。
|
Web App开发 JavaScript 前端开发
使用Python调用JavaScript进行网页自动化操作
使用Python调用JavaScript进行网页自动化操作
|
Android开发
Android面试高频知识点(1) 图解 Android 事件分发机制
在Android开发中,事件分发机制是一块Android比较重要的知识体系,了解并熟悉整套的分发机制有助于更好的分析各种点击滑动失效问题,更好去扩展控件的事件功能和开发自定义控件,同时事件分发机制也是Android面试必问考点之一,如果你能把下面的一些事件分发图当场画出来肯定加分不少。废话不多说,总结一句:事件分发机制很重要。
430 9
|
安全 Cloud Native Shell
云上攻防:云原生篇&Docker容器逃逸
本文介绍了Docker的基本概念及其对渗透测试的影响,重点讲解了容器逃逸的方法。Docker是一种轻量级的容器技术,与虚拟机相比,具有更高的便携性和资源利用率。然而,这也带来了安全风险,特别是容器逃逸问题。文章详细描述了三种常见的容器逃逸方法:不安全的配置、相关程序漏洞和内核漏洞,并提供了具体的检测和利用方法。此外,还介绍了几种特定的漏洞(如CVE-2019-5736和CVE-2020-15257)及其复现步骤,帮助读者更好地理解和应对这些安全威胁。
845 0
云上攻防:云原生篇&Docker容器逃逸
|
图形学
Unity构造器注入+配置文件小实例
Unity构造器注入+配置文件小实例
正则表达式
正则表达式
|
存储 前端开发 JavaScript
React Hooks 的替代方案有哪些?
【5月更文挑战第28天】React Hooks 的替代方案有哪些?
204 2
【编程题-错题集】分组(枚举 + 二分)
【编程题-错题集】分组(枚举 + 二分)
|
Java 编译器
Java 最常见的面试题:try-catch-finally 中哪个部分可以省略?
Java 最常见的面试题:try-catch-finally 中哪个部分可以省略?