• Spring【五大类注解的存储和读取Bean方法注解】


    🍎一. 五大类存储 Bean 对象

    上一篇博客我们已经可以实现基本的 Spring 读取和存储对象的操作了,但在操作的过程中我们发现读取和存储对象并没有想象中的那么“简单”,所以接下来我们要学习更加简单的操作 Bean 对象的⽅法

    在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,也就是我们接下来要学习 Spring 中的相关注解,来存储和读取 Bean 对象

    🍒1.1 配置spring-config.xml扫描路径

    我们在resources文件下系创建一个带有.xml类型的文件,不是必须要设置成spring-config.xml这个名称的文件,只是方便我们辨识,或者工作中使用

    之前我们存储 Bean 时,需要在 spring-config 中添加⼀⾏ bean 注册内容才⾏,这样会很麻烦,有可能我们在编写程序时忘记注册Bean的属性就会报错,不仅降低了工作效率,还增加了编程时产生的错误,⽽现在我们只需要⼀个注解就可以替代之前要写⼀⾏配置的尴尬了,不过在开始存储对象之前,我们先要来点准备:⼯作配置spring-config.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:content="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 https://www.springframework.org/schema/context/spring-context.xsd">
        <content:component-scan base-package="com.beans"></content:component-scan>
    </beans>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    在这里插入图片描述

    🍒1.2 添加五大类注解存储 Bean 对象

    想要将对象存储在 Spring 中,有两种注解类型可以实现:

    1. 类注解@Controller、@Service、@Repository、@Component、@Configuration

    🍉1.2.1 @Controller(控制器存储)

    使⽤ @Controller 存储 bean 的代码如下所示:

    @Controller
    public class UserController {
        public void sayHi(String name){
            System.out.println("Hi"+ name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    读取 bean 的代码:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
             UserController controller = context.getBean("userController",UserController.class);
            UserService service = context.getBean("userService",UserService.class);
            controller.sayHi("张三");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    🍉1.2.2 @Service(服务存储)

    使⽤ @Service 存储 bean 的代码如下所示:

    @Service
    public class UserService {
        public void sayHi(String name) {
            System.out.println("Hi" + name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    读取 bean 的代码:

    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
             UserController controller = context.getBean("userController",UserController.class);
            UserService service = context.getBean("userService",UserService.class);
            service.sayHi("李四");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    🍉1.2.3 @Repository(仓库存储)

    以上同理

    @Repository
    public class UserRepository {
            public void sayHi(String name){
                    System.out.println("你好:" + name);
            }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
             UserController controller = context.getBean("userController",UserController.class);
             UserService service = context.getBean("userService",UserService.class);
            UserRepository repository = context.getBean("userRepository",UserRepository.class);
    //        controller.sayHi("张三");
    //        service.sayHi("李四");
            repository.sayHi("王五");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    🍉1.2.4 @Component(组件存储)

    以上同理

    @Component
    public class UserComponent {
        public void sayHi(String name){
            System.out.println("你好:" + name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
             UserController controller = context.getBean("userController",UserController.class);
             UserService service = context.getBean("userService",UserService.class);
            UserRepository repository = context.getBean("userRepository",UserRepository.class);
            UserComponent component = context.getBean("userComponent",UserComponent.class);
    //        controller.sayHi("张三");
    //        service.sayHi("李四");
    //        repository.sayHi("王五");
            component.sayHi("赵六");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    🍉1.2.5 @Configuration(配置存储)

    以上同理

    @Configuration
    public class UserConfiguration {
        public void sayHi(String name){
            System.out.println("你好:" + name);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
     public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
             UserController controller = context.getBean("userController",UserController.class);
             UserService service = context.getBean("userService",UserService.class);
            UserRepository repository = context.getBean("userRepository",UserRepository.class);
            UserComponent component = context.getBean("userComponent",UserComponent.class);
            UserConfiguration configuration = context.getBean("userConfiguration",UserConfiguration.class);
    //        controller.sayHi("张三");
    //        service.sayHi("李四");
    //        repository.sayHi("王五");
    //        component.sayHi("赵六");
            configuration.sayHi("七七");
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    🍒1.3 五大注解类小结

    🍉1.3.1 为什么使用五大类注解

    在这里插入图片描述
    我们拿去银行办业务举例:
    @Controller层就是保安,先要进行检查验证,然后到达Service服务厅询问业务,不同的业务来到Repository,不同的窗口,然后进行相应的工作人员办理业务!

    🍉1.3.2 五大类注解之间的关系

    我们可以在注解类的源码内看到@Controller、@Service、@Repository、@Configuration都是继承@Component
    也就是说@Component是@Controller、@Service、@Repository、@Configuration这四个类的父类
    在这里插入图片描述

    🍉1.3.3 getBean() 命名

    我们会在前面的存储和获取对象时发现,为什么在getBean方法获取Bean对象时要将Bean对象的属性名输入为小驼峰型?
    在这里插入图片描述
    我们在源码就可以看出这三种情况,我就不过多解释了,大家应该都能读懂

    🍎二.方法注解的存储

    🍒2.1 方法注解的存储

    🍉2.1.1 @Bean注解的使用

    我们先创建一个班级类

    @Component
    public class User {
        private String name;
        private int Id;
    
        @Override
        public String toString() {
            return "User{" +
                    "name='" + name + '\'' +
                    ", Id=" + Id +
                    '}';
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getId() {
            return Id;
        }
    
        public void setId(int id) {
            Id = id;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    之后在创建一个方法类我们要注意在定义方法Bean时也要定义五大类注解其一因为⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中才能获取到

    @Component
    public class UserBean {
        @Bean
        public User user1(){
            User user = new User();
            user.setId(1);
            user.setName("张三");
            return user;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    public class Test {
        public static void main(String[] args) {
            ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
            UserConfiguration configuration = context.getBean("userConfiguration",UserConfiguration.class);
            User user = (User) context.getBean("user1");
            System.out.println(user.toString());
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    🍉2.1.2 @Bean的的重命名

    可以通过设置 name 属性给 Bean 对象进⾏重命名操作,如下图所示:
    在这里插入图片描述
    这个重命名的 name 其实是⼀个数组,⼀个 bean 可以有多个名字:

    @Bean(name = {"u1", "us1"})
    public User user1() {
       User user = new User();
       user.setId(1);
       user.setName("Java");
       return user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在Bean name重名的时候时区分大小写的
    在这里插入图片描述

    在这里插入图片描述
    我们会发现会找不到bena name抛出错误
    在这里插入图片描述

    🍒2.2 方法注解的获取(对象注⼊@Autowired 或 @Resource)

    获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊
    对象装配(对象注⼊)的实现⽅法以下 3 种:

    1. 属性注⼊
    2. Setter 注⼊
    3. 构造⽅法注⼊

    🍉2.2.1 属性注⼊

    属性注⼊是使⽤ @Autowired 实现的,将 Service 类注⼊到 Controller 类中。
    Service 类的实现代码如下:

    public class Test {
        public static void main(String[] args) {
              UserConterller2 conterller2 = context.getBean(UserConterller2.class);
                      conterller2.sayHi();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @Component
    public class UserConterller2 {
       //对象注入方式1: 属性注入
       @Autowired
        private UserService userService;
        public void sayHi(){
            userService.sayHi("属性注入");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    在这里插入图片描述

    🍉2.2.2 Setter注入

    与上同理
    在这里插入图片描述

    🍉2.2.2 构造方法注入

    在这里插入图片描述

    🍉2.2.3 同⼀类型多个 @Bean 报错

    当出现以下多个 Bean,返回同⼀对象类型时程序会报错,如下代码所示:

    @Component
    public class Users {
       @Bean
       public User user1() {
         User user = new User();
         user.setId(1);
         user.setName("Java");
         return user;
       }
         @Bean
         public User user2() {
         User user = new User();
         user.setId(2);
         user.setName("MySQL");
         return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    @Controller
    public class UserController4 {
       // 注⼊
       @Resource
       private User user;
       public User getUser() {
         return user;
       }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    以上程序的执⾏结果如下:
    在这里插入图片描述
    报错的原因是,⾮唯⼀的 Bean 对象

    解决同⼀个类型,多个 bean 的解决⽅案有以下两个:
    ● 使⽤ @Resource(name=“user1”) 定义
    ● 使⽤ @Qualifier 注解定义名称

    同⼀类型多个 Bean 报错处理

    🍎三.总结

    🍒3.1小结

    1. 将对象存储到 Spring 中:
      a. 使⽤类注解:@Controller、@Service、@Repository、@Configuration、@Component【它们之间的关系】
      b. 使⽤⽅法注解:@Bean【注意事项:必须配合类注解⼀起使⽤】
    2. Bean 的命名规则:⾸字⺟和第⼆个字⺟都⾮⼤写,⾸字⺟⼩写来获取 Bean,如果⾸字⺟和第⼆个字⺟都是⼤写,那么直接使⽤原 Bean 名来获取 Bean。
    3. 从 Spring 中获取对象:
      a. 属性注⼊
      b. Setter 注⼊
      c. 构造函数注⼊(推荐)
    4. 注⼊的关键字有:
      a. @Autowired
      b. @Resource
    5. @Autowired 和 @Resource 区别:出身不同; 使⽤时设置参数不同 @Resource ⽀持更多的参数,⽐如 name。
    6. 解决同⼀类型多个 Bean 的报错:
      a. 使⽤ @Resource(name="")
      b. 使⽤ @Qualifier("")

    🍒3.2 三种注⼊优缺点分析

    ●属性注⼊的优点是简洁,使⽤⽅便;缺点是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)

    ●构造⽅法注⼊是 Spring 推荐的注⼊⽅式,它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了,它的优点是通⽤性,官方推荐,在使⽤之前⼀定能把保证注⼊的类不为空

    ●Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法,所有 Spring 现版本已经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了

    🍒3.3 @Autowired 和 @Resource 的区别

    ●出身不同:@Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解

    ●使⽤时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如name ,type设置,根据名称获取 Bean

    ●注入方法数不同: @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注⼊和属性注⼊,不能⽤于构造函数注⼊

  • 相关阅读:
    NOIP2000提高组第二轮T2:乌龟棋
    七天.NET 8操作SQLite入门到实战 - (2)第七天Blazor班级管理页面编写和接口对接
    Gateway网关动态路由配置(YAML格式 + JSON格式)
    爱上开源之boot4go-dockerui-剧透篇
    FPGA GTH 全网最细讲解,aurora 8b/10b编解码,HDMI视频传输,提供2套工程源码和技术支持
    常用设计模式总结
    怎么把两个PDF合并成一个?建议收藏这些合并的方法
    MacOS使用clang
    jwt简介
    RocketMQ的常见应用样例及其实现
  • 原文地址:https://blog.csdn.net/m0_59735420/article/details/127951996