Spring(存储Bean对象五大类注解,获取Bean对象三种注入方式)

news2024/10/1 5:39:56

目录

1. 先进行配置扫描路径

2. 存储 Bean 对象 ( 添加注解存储 Bean 对象)

2.1 @Controller [控制器存储]

2.2 @Service [服务存储]

2.3 @Repository [仓库存储]

2.4 @Configuration [配置存储]

2.5 @Component [组件存储]

2.6 五大类注解的作用和关系

2.7 Bean的命名规则

2.8 使用方法注解 @Bean

2.8.1 重命名 Bean

3. 获取 Bean 对象 (对象装配) 

3.1 属性注入

3.2 构造方法注入

3.3 Setter注入

3.4 面试题: 三种注入优缺点分析

3.5 @Resource:另一种注入关键字

面试题: @Autowired 和 @Resource 的区别

3.6 @Bean 将一个类型的对象注入多次的问题:


在上一篇中,可以看到,创建Spring需要三步,存 bean 需要三步, 取 bean 需要三步,感觉这个读取和存储对象的步骤并没有想象的那么 "简单" 啊

所以本篇将学习通过 "使用注解" 来更简单的存储和读取对象


前面在存储 Bean 时,需要在 spring-config 中添加一行 bean 注册内容,这个XML文件有一点不好的是调试,而且XML文件报错了是不影响项目运行的,即使报错了,也可能发现不了.

1. 先进行配置扫描路径

<?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.bit.service"></content:component-scan>
</beans>

在 spring 配置文件中设置 bean 的扫描根路径


2. 存储 Bean 对象 ( 添加注解存储 Bean 对象)

使用 5 大类注解实现,就不用在spring-config 中添加一行 bean 注册内容了

2.1 @Controller [控制器存储]

package com.beans;

import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    public void sayHi() {
        System.out.println("你好,UserController!");
    }
}
import com.beans.UserController;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        //1. 先得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");

        //2. 得到 bean
        UserController controller = context.getBean("userController",UserController.class);

        //3. 使用 bean
        controller.sayHi();
    }
}

2.2 @Service [服务存储]

import com.beans.UserController;
import com.beans.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserService service = context.getBean("userService",UserService.class);
        service.sayHi();
    }
}
package com.beans;

import org.springframework.stereotype.Service;

@Service
public class UserService {
    public void sayHi() {
        System.out.println("你好,Service!");
    }
}

2.3 @Repository [仓库存储]

import com.beans.UserRepository;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserRepository repository = context.getBean("userRepository",UserRepository.class);
        repository.sayHi();

    }
}
package com.beans;

import org.springframework.stereotype.Repository;

@Repository
public class UserRepository {
    public void sayHi() {
        System.out.println("你好,Repository!");
    }
}

2.4 @Configuration [配置存储]

package com.beans;

import org.springframework.context.annotation.Configuration;

@Configuration
public class UserConfiguration {
    public void sayHi() {
        System.out.println("你好,Configuration!");
    }
}
import com.beans.UserConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        //1. 先得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");        UserConfiguration configuration = context.getBean("userConfiguration",UserConfiguration.class);
        configuration.sayHi();
    }
}

2.5 @Component [组件存储]

package com.beans;

import org.springframework.stereotype.Component;

@Component
public class UserComponent {
    public void sayHi() {
        System.out.println("你好,Component!");
    }
}
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserComponent component = context.getBean("userComponent",UserComponent.class);
        component.sayHi();
    }
}

2.6 五大类注解的作用和关系

(1) 作用:

这么多注解的作用是,如果一个项目特别大的情况下,文件会非常杂乱的,所以就是通过注解,来让程序员看到注解后就知道了,当前类的作用

程序的最基础⼯程分层,调⽤流程如下

 (2) 关系:

在五大注解类中 Component 可以当做其他注解的父类

其他类之间的关系可以当做是兄弟

下面看一下源码

2.7 Bean的命名规则

在前按照规范"大驼峰"取类名,然后getBean按照规范"小驼峰"是可以运行成功的

 而写如果写一个这样的类

 但是如果,这样写就可以运行成功

 那么 Bean 的命名规则到底应该是什么样的

所以根据这个规则,正常下命名,如果类的前两个字符都为大写字母,就写原名字

如果只有第一个字母为大写,那就按"小驼峰" 来命名


2.8 使用方法注解 @Bean

@Bean 是加在方法上的,并且只使用一个 @Bean 是无法将对象存储到容器中的,所以还要给类加个注解

Bean 就是类注解的基础上缩小范围

package com.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
   @Bean  //[只使用一个 @Bean 是无法将对象存储到容器中]
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        //1. 先得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        User user = context.getBean("user1",User.class);
//        User user = context.getBean(User.class);

        System.out.println(user);

    }
}
package com.beans;

public class User {
    private int id;
    private String name;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

2.8.1 重命名 Bean

可以通过设置 name 属性给 Bean 对象进⾏重命名操作

package com.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
   @Bean(name = "userinfo")  //[只使用一个 @Bean 是无法将对象存储到容器中]
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }
}

@Bean 命名规则,当没有设置name属性时,那么 bean 默认的名称就是方法名,

当设置name属性后,只能通过重命名的name属性对应的值来获取,也就是说再使用方法就获取不到 bean 对象了,

并且也可以 一个bean 有多个名字,像数组一样在{}中写上多个名字,就可以了 


3. 获取 Bean 对象 (对象装配) 

获取 Bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注入

3.1 属性注入

通过 @Autowired 就可以属性注入

package com.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {
    // 对象注入1: 属性注入
    @Autowired
    private UserService userService;

    public void sayHi() {
        userService.sayHi();
    }
}
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        //1. 先得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController2 controller2 = context.getBean(UserController2.class);
        controller2.sayHi();
    }
}

3.2 构造方法注入

写构造方法,参数传入要注入的对象,然后写上注解 @AutoWired (如果当前类中只有一个构造方法,那就可以省略注解)

package com.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {

    //使用构造方法实现 bean 注入(官方推荐写法)
    private UserService userService;

    @Autowired
    public UserController2(UserService userService) {
//        userService = new UserService(); //传统的写法
        this.userService = userService;
    }

    public void saHi() {
        userService.sayHi();
    }
}

3.3 Setter注入

Setter 注入,写要注入的属性的 setter方法,然后加上注解 @Autowired

package com.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController2 {
    //3. 使用 Setter 注入
    private UserService userService;

    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public void sayHi() {
        userService.sayHi();
    }
}

3.4 面试题: 三种注入优缺点分析

属性注入 / 构造方法注入 / Setter注入

  1. 属性注入特点: 写法简单,只适用于 IoC容器,通用性不好
  2. 构造方法注入: 这种写法从 spring 3.4后就成推荐写法了,通用性更好,能确保在使用注入对象之前,此注入对象一定是初始化过的.当构造方法注入参数过多时,开发者就要检查自己所写的代码是否符合单一设计原则的规范了.
  3. Setter 注入特点:这种写法是早期 Spring 版本的推荐写法(大概是3.4前),Setter 注入通用性没有构造方法注入通用

3.5 @Resource:另一种注入关键字

@Resource: 支持 属性注入 和 Setter 注入,但不支持构造方法注入

面试题: @Autowired 和 @Resource 的区别

相同点: 都可以实现将一个对象注入到类中
不同点:
  1. 出身不同: @Resource 来自 JDK ;    @Autowired 是 Spring 框架提供的
  2. 用法不同: @Resource 用于 属性注入/Setter 注入 ;  @ Autowired 用于 属性注入/构造方法注入/Setter注入
  3. 支持的参数不同: @Resource 支持更多的参数设置,name/type....  ;  而 @Autowired 只支持 required 参数设置

3.6 @Bean 将一个类型的对象注入多次的问题:

  解决方法

(1) 精确的描述 bean 的名称 (将注入的名称写对)

(2) 使用 @Resource 设置 name 的方式来重命名注入对象

(3) 如果限定不能删除 @Autowired ,那就可以再加上使用 @Qualifier,来删选 bean 对象

 

 解决方法

(1) 精确的描述 bean 的名称 (将注入的名称写对)

package com.beans;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {

    @Autowired //[属性注入/字段注入]
    private User user2;

    public void sayHi() {
        System.out.println("User -> " + user2);
    }
}
import com.beans.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class app {
    public static void main(String[] args) {
        //1. 先得到上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        UserController controller = context.getBean(UserController.class);
        controller.sayHi();
    }
}
package com.beans;

import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
   @Bean(name = "userinfo")  //[只使用一个 @Bean 是无法将对象存储到容器中]
    public User user1() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        return user;
    }

    @Bean
    public User user2() {
        User user = new User();
        user.setId(2);
        user.setName("李四");
        return user;
    }
}

(2) 使用 @Resource 设置 name 的方式来重命名注入对象

(3) 如果限定不能删除 @Autowired ,那就可以再加上使用 @Qualifier,来删选 bean 对象

 


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/54827.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于文化算法优化的神经网络预测研究(Matlab代码实现)

目录 1 文化优化算法 2 人工神经网络 3 基于文化算法优化的神经网络预测研究&#xff08;Matlab代码实现&#xff09;运行结果 4 参考文献 5 Matlab代码实现 1 文化优化算法 大自然里的各种生物在生存环境中相互竞争&#xff0c;优胜劣汰&#xff0c;不断进化&#xff0…

股票编程交易接口怎样自动设置止损?

目前随着国内二级股市已处于相对较高的水平&#xff0c;但是对于高净值的用户来说&#xff0c;在量化投资市场上使用股票编程交易接口系统上具有低波动性和自动交易的定量对冲投资模型体系&#xff0c;包括了一些高性价比、大型基金和长期投资的资产品种&#xff0c;所以大家在…

瑞吉外卖-B站最火的新手入门SpringBoot+Mybatis+Redis项目详细教程来了

&#x1f531;项目介绍 项目地址 GitHub&#xff1a;https://github.com/codermast/Takeout-food 对你有用的话&#xff0c;希望能给项目点个Star&#xff0c;非常感谢。 对于项目的任何问题&#xff0c;或者你在本地部署时遇到的无法解决的问题&#xff0c;都可以提交issues…

迭代器模式

文章目录思考迭代器模式1.迭代器模式的本质2.何时选用迭代器模式3.优缺点4.实现手动实现迭代器模式java迭代器模式思考迭代器模式 迭代器模式(Iterator Pattern)是常用的设计模式&#xff0c;属于行为型模式。如果我们的集合元素是用不同的方式实现的&#xff0c;有数组&#…

利用EasyDL制作一个简单的图片识别小项目

主要是利用EasyDL制作一个简单的傻瓜式猫狗图片识别&#xff0c;利用EasyDL&#xff0c;只需要几步简单的点击即可 *主要的步骤&#xff1a; 1.准备数据 2.训练模型 3.部署 4.H5 * 1.首先创建两个文件夹cat和dog分别搜集至少20张以上的猫和狗的图片&#xff08;如果不足20张&…

【High 翻天】Higer-order Networks with Battiston Federico (1)

目录前言高阶网络的表示高阶相互作用的初等表示表示之间的关系总结前言 Ginestra Bianconi 的一篇综述1和一本书2展开的故事。 书还没有开始看&#xff0c;先看看综述吧。综述提供了一个关于超越成对交互的网络新兴领域的概述。 讨论了高阶网络的表示&#xff0c;主要是其中…

HBase Shell 基本操作

首先确保你的hbase集群已经开启 进入 HBase 客户端命令行 namespace 使用help查看命令用法&#xff0c;并创建命名空间 查看所有命名空间 DDL 在 bigdata 命名空间中创建表格 student&#xff0c;两个列族。info 列族数据维护的版本数为 5 个&#xff0c; 如果 VERSIONS …

Arduino UNO通过SPI串行方式驱动LCD12864液晶屏

LCD12864液晶屏简介 LCD12864带中文字库图形点阵式液晶显示器&#xff0c;可配合各种单片机可完成中文汉字、英文字符和图形显示&#xff0c;可构成全中文人机交互图形界面&#xff0c;模块具有功耗低、显示内容丰富等特点而应用广泛。它是利用液晶经过处理后能改变光线的传播…

前端面试八股文(详细版)—上

本文将详细讲解 HTML 、CSS 、JavaScript 、计算机网络知识等方面的内容&#xff0c;Vue 、React 、git 、项目开发实例等内容放在下篇&#xff0c;预祝各位成功上岸&#xff01; 第一板块&#xff1a;JavaScript ES6 新增内容 1、模板字符串 变量名写在 ${} 中&#xff0c;$…

可用性测试的理解

可用性测试是通过观察有代表性的用户&#xff0c;完成产品的典型任务&#xff0c;从而界定出可用性问题并解决的过程。通俗地讲就是“观察用户使用产品”。 可用性测试到底测的什么? a 有效性(独立完成任务的比例) b 完成任务的时间 c 满意度(用户主观评价操作难易/好感/是否再…

回归预测 | MATLAB实现贝叶斯优化门控循环单元(BO-GRU)多输入单输出

回归预测 | MATLAB实现贝叶斯优化门控循环单元(BO-GRU)多输入单输出 目录回归预测 | MATLAB实现贝叶斯优化门控循环单元(BO-GRU)多输入单输出基本介绍背景回顾模型介绍程序设计学习总结参考资料致谢基本介绍 本次运行测试环境MATLAB2020b&#xff1b; 本次预测基本任务是回归&a…

【JavaEE】JavaScript(基础语法)2

努力经营当下&#xff0c;直至未来明朗&#xff01; 文章目录前言四、【运算符】五、条件、三元、switch、循环语句六、数组七、函数八、 对象THINK前言 一个人最大的痛苦来自于对自己无能的愤怒&#xff01; Hi&#xff0c;这里依旧是秃头宝贝儿&#xff01; 本文依旧是介绍…

win10录屏功能怎么打开,详细图文教学,轻松学会

在生活中&#xff0c;有不少人的电脑&#xff0c;都是WIN10系统&#xff0c;在学习工作或者娱乐的过程中想要录下视频&#xff0c;就需要使用win10录屏功能。Win10录屏功能怎么打开&#xff1f;Windows自带的屏幕录制功能如何使用&#xff1f;不要着急&#xff0c;今天小编将向…

尚医通-微信支付

流程梳理 依赖和工具类 <dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version> </dependency><dependency><groupId>com.example</groupId><ar…

Collagen胶原蛋白修饰亚油酸linoleic acid/甲磺酸酯Mesylate/磷酸三苯酯TPP

产品名称&#xff1a;胶原蛋白修饰亚油酸 英文名称&#xff1a;Collagen-linoleic acid 用途&#xff1a;科研 状态&#xff1a;固体/粉末/溶液 产品规格&#xff1a;1g/5g/10g 保存&#xff1a;冷藏 储藏条件&#xff1a;-20℃ 储存时间&#xff1a;1年 胶原蛋白是一种细胞外蛋…

Mybatis:Mybatis中特殊Sql执行(6)

特殊Sql执行1. 模糊查询2. 批量删除3. 动态设置表名4. 添加功能获取自增的主键5. 整体代码1. 模糊查询 /*** 根据用户名进行模糊查询* param moHu* return*/List<User> getUserByLike(Param("moHu") String moHu);<!--List<User> getUserByLike(Param…

Java多线程之相关拓展(静态代理和Lamda表达式演变)

Java多线程拓展之静态代理和Lamda表达式演变一、静态代理1、概念2、优点3、样例二、Lamda表达式&#xff08;演变过程展示&#xff09;1、定义一个函数式接口并实现类&#xff08;最初状态&#xff09;2、静态内部类&#xff08;状态演变2&#xff09;3、局部内部类&#xff08…

英国G5生物医学类专业IB成绩要求多高?

生物医学类专业一向是申请热门。最近几年&#xff0c;由于新冠疫情的原因&#xff0c;相关专业申请竞争更加激烈了。英国G5生物医学类专业IB成绩要求多高&#xff1f;话说&#xff0c;IB申请英国的生物医学类专业&#xff0c;需要做好哪些准备&#xff1f;英国大学的生物医学类…

Spring Data JPA使用Pageable 参数Thymeleaf 视图进行分页

在上一个教程中&#xff0c;我们看到了如何在Spring MVC控制器方法中使用参数。以下示例显示了如何将 Spring 数据分页与 Thymeleaf 视图一起使用。我们还将使用注释来更改默认页面大小。PageablePageableDefault 例 实体 package com.example;import jakarta.persistence.E…

VS系列多通道振弦温度采发仪的选型与开机操作

VS A B C D E VS&#xff1a;无线型振弦传感器采发仪 A&#xff1a;内嵌核心测量模块数量&#xff08;1~4 个&#xff09; B&#xff1a;两位数字表示的振弦通道数量&#xff08;02、04、08、16&#xff09; C&#xff1a;T 表示带有温度测量通道 D&#xff1a;是否有…