• Spring框架(三)Spring注解和获取Bean对象详解


    一,什么是基于Java的Spring注解配置,具体注解的例子

    • 基于Java的配置,允许你在少量的Java注解的帮助下,进行你的大部分Spring配置而非通过XML文件。
    • 以@Configuration 注解为例,它用来标记类可以当做一个bean的定义,被Spring IOC容器使用。
    • 另一个例子是@Bean注解,它表示此方法将要返回一个对象,作为一个bean注册进Spring应用上下文。
    @Configuration
    public class StudentConfig {
        @Bean
        public StudentBean myStudent() {
            return new StudentBean();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    二,更好的将Bean存储在Spring中⭐

    1,前置工作,在配置文件中设置Bean根路径

    想要将对象成功的存储到 Spring 中,我们需要配置⼀下存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中。
    在 spring-config.xml 添加如下配置:

     <!-- 设置需要存储在Spring中的bean根目录-->
        <content:component-scan base-package="com.beans"></content:component-scan>
    
    • 1
    • 2

    在这里插入图片描述

    2,添加注解存储Bean对象

    有两种方式实现注解:

    • 类注解:@Controller(控制器)、@Service(服务)、@Repository(仓库)、@Component(组件)、@Configuration(配置)
    • 方法注解:@Bean

    2.1 @Controller(控制器存储)

    代码示例:

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

    注意事项:
    ①即使在spring配置文件配置了bean的扫描路径,五大类注解也是不能省略的
    ②即使加了五大类注解,但类没有放在spring配置的Bean路径下,也是不能讲类注解到spring

    此时我们先使用之前读取对象的方式来读取上面的UserController 对象,如下代码所示:

    public class Application {
        public static void main(String[] args) {
    // 1.得到 spring 上下⽂
            ApplicationContext context =
                    new ClassPathXmlApplicationContext("spring-config.xml");
    // 2.得到 bean
            UserController userController = (UserController)
                    context.getBean("userController");
    // 3.调⽤ bean ⽅法
            userController.sayHi("Bit");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    2.2@Service(服务)

    代码示例:

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

    2.3 @Repository(仓库存储)

    代码示例:

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

    2.4 @Component(组件存储)

    代码示例:

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

    2.5 @Configuration(配置存储)

    代码示例:

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

    3,注意 Bean 的命名

    通过上面示例,我们可以看出,通常我们 bean 使用的都是标准的大驼峰命名,而读取的时候首字母小写就可以获取到 bean 了,如下图所示:

    在这里插入图片描述

    4,方法注解 @Bean

    • 类注解是添加到某个类上的,而方法注解是放到某个方法上的,如以下代码的实现:
      1.方法注解要配合类注解使用
    @Component
    public class Users {
        @Bean
        public User user1() {
            User user = new User();
            user.setId(1);
            user.setName("Java");
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    2.重命名 Bean

    @Component
    public class Users {
        @Bean(name = {"u1"})
        public User user1() {
            User user = new User();
            user.setId(1);
            user.setName("Java");
            return user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5,既然功能是⼀样的,为什么需要这么多的类注解呢

    那么为什么需要怎么多的类注解也是相同的原因,就是让程序员看到类注解之后,就能直接了解当前类的用途,比如:
    @Controller:表示的是业务逻辑层
    @Servie:服务层
    @Repository:持久层
    @Configuration:配置层

    在这里插入图片描述

    三,@Component, @Controller, @Repository, @Service 有何区别

    关系:

    • 查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现Component类是Controller,Repository, Service ,Configuration的父类

    区别:

    • @Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境中
    • @Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中
    • @Service:此注解是组件注解的特化。它不会对 @Component 注解提供任何其他行为。您可以在服务层类中使用 @Service 而不是 @Component,因为它以更好的方式指定了意图
    • @Repository:这个注解是具有类似用途和功能的 @Component 注解的特化。它为 DAO 提供了额外的好处。它将 DAO 导入 IoC 容器,并使未经检查的异常有资格转换为 Spring DataAccessException

    四,怎样开启注解装配

    • 注解装配在默认情况下是不开启的,为了使用注解装配,我们必须在Spring配置文件中配置 context:annotation-config/元素

    五,获取Bean对象(对象装配)

    获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入
    对象装配(对象注⼊)的实现⽅法以下 3 种:
    1.属性注入
    2.构造方法注入
    3.Setter 注入

    1.属性注入

    属性注入是使用 @Autowired 实现的,将 Service 类注入到 Controller 类中

    • @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)。@Autowired 注解提供了更细粒度的控制,包括在何处以及如何完成自动装配。它的用法和@Required一样,修饰setter方法、构造器、属性或者具有任意名称和/或多个参数的PN方法
    import org.springframework.beans.factory.annotation.Autowired; 
    import org.springframework.stereotype.Controller;
    @Controller
    public class UserController {
        // 注⼊⽅法1:属性注⼊
        @Autowired
        private UserService userService;
        public User getUser(Integer id) {
            return userService.getUser(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.构造方法注入

    构造方法注入是在类的构造方法中实现注入,如下代码所示:

    @Controller
    public class UserController2 {
        // 注⼊⽅法2:构造⽅法注⼊
        private UserService userService;
        @Autowired
        public UserController2(UserService userService) {
            this.userService = userService;
        }
        public User getUser(Integer id) {
            return userService.getUser(id);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.Setter 注入

    Setter 注入和属性的 Setter 方法实现类似,只不过在设置 set 方法的时候需要加上 @Autowired 注解,如下代码所示:

    @Controller
    public class UserController3 {
        // 注⼊⽅法3:Setter注⼊
        private UserService userService;
        @Autowired
        public void setUserService(UserService userService) {
            this.userService = userService;
        }
        public User getUser(Integer id) {
            return userService.getUser(id);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    六,@Autowired和@Resource之间的区别

    • 出身不同:@Autowired是Spring的实现,@Resource来自于JDK
    • 支持的参数设置不同:@Autowired只支持required参数设置,,而@Resource支持很多参数,比如name,type等
    • 支持的注入类型不同:@Autowired可用于:构造函数、成员变量、Setter方法, 而@Resource可用于:成员变量、Setter方法

    七,@Qualifier 和@RequestMapping 注解有什么用

    • 当您创建多个相同类型的 bean 并希望仅使用属性装配其中一个 bean 时,您可以使用@Qualifier 注解和 @Autowired 通过指定应该装配哪个确切的 bean 来消除歧义
    • @RequestMapping 注解用于将特定 HTTP 请求方法映射到将处理相应请求的控制器中的特定类/方法。此注释可应用于两个级别:
      ①类级别:映射请求的 URL
      ②方法级别:映射 URL 以及 HTTP 请求方法
  • 相关阅读:
    【STL面试】说说 vector 和 list 的区别,分别适用于什么场景?
    学习SpringMvc第三战-利用SpringMvc实现CRUD
    (JAVA)[COCI2006-2007#2] ABC
    Java构件技术
    计算机毕业设计ssm基于SSM的社区疫情防控管理信息系统的设计与实现khjit系统+程序+源码+lw+远程部署
    算法基础课第二部分
    计算机操作系统:二级页表原理
    java计算机毕业设计夕阳红养老院系统源码+系统+数据库+lw文档+mybatis+运行部署
    vue2不同版本下如何分环境打包
    日志技术-logback
  • 原文地址:https://blog.csdn.net/qq_55660421/article/details/126267625