5-Spring更简单的读取和存储对象

这篇具有很好参考价值的文章主要介绍了5-Spring更简单的读取和存储对象。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.存储Bean对象

1.1.前置工作:在配置文件中设置bean扫描的根路径(重要)

1.2.添加注解存储Bean对象到Spring中

1.2.1.类注解(添加到某个类上,将当前的类存储到Spring中):@Controller,@Service,@Repository,@Component,@Configuration

关于类注解的bean的命名规则:

PS:为什么要这么多类注解?

1.2.2.方法注解(添加到某个方法上,将当前方法返回的对象存储到Spring中):@Bean

2.获取Bean对象(对象装配/对象注入)

2.1.属性注入:是使用@Autowired(自动写入)注解实现的

2.2.构造方法注入:是在类的构造方法中实现注入

2.3.Setter注入:和属性的Setter方法实现类似,只不过在设置set方法时需要加上@Autowired注解

PS:(经典面试题)属性注入,构造方法注入和Setter注入的异同分析?

2.4.另一种注入关键字:@Resource

2.4.1.属性注入:

2.4.2.Setter注入:

PS:(经典面试题)@Autowired和@Resource的区别?

2.5.同一类型多个@Bean报错

处理方法:

2.5.1.使用正确的bean name来获取(有限制,不用于大规模使用)

2.5.2.使用@Resource注解设置name属性(最简单)(@Autowired只有一个参数,没有name属性)

2.5.3.使用@Autowired + @Qualifier


在Spring中想要更简单地读取和存储对象的核心是使用注解。(Spring,SpringBoot,SpringMVC中的注解是通用的)

1.存储Bean对象

之前需要在spring-config.xml文件中添加bean标签注册内容,而xml的问题在于出错的概率和排错的难度都高:

  • 无法像代码一样调试,只能人工去看;
  • 有错后IDEA不会提示/即使有提示,程序也能正常运行;
  • 写法不方便。

而现在只需要一个注解就ok~

1.1.前置工作:在配置文件中设置bean扫描的根路径(重要)

要想将对象存储到Spring中,需要配置存储对象的扫描包路径,只有被配置的包下的所有类,添加了注解才能被正确地识别并保存到Spring中。

在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">
    <!--设置需要存储到spring中的bean根目录-->
    <content:component-scan base-package="com.beans"></content:component-scan>
</beans>

其中:

<content:component-scan base-package="com.beans"></content:component-scan>

content:正文;

component-scan:扫描组件;

base-package:根目录(写自己的)。

规定了需要存储到Spring中的类的根目录的扫描路径,否则要扫描当前项目下的所有的类(要加到Spring中的和不要加到Spring中的类),这样提高了效率。

base-package是当前路径当前路径下的所有子路径下的所有的bean。

1.2.添加注解存储Bean对象到Spring中

1.2.1.类注解(添加到某个类上,将当前的类存储到Spring中):@Controller,@Service,@Repository,@Component,@Configuration

使用这5大类注解中的任意一种都可以将bean存储到Spring中。

注:

  1. 即使在Spring配置文件中配置了bean的扫描路径,5大类注解依旧不能省略。
  2. 即使加了5大类注解,但类没有放在Spring配置的bean路径下,那么也是不能将类注入到Spring中的。

①@Controller(控制器存储)

@Controller //将当前对象存储到Spring中
public class UserController {
    public void sayHi(String name) {
        System.out.println("Hi," + name);
    }
}

用之前读取对象的方式来读取:

public class App {
    public static void main(String[] args) {
        //1.获取Spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //2.得到bean
        UserController userController = (UserController) context.getBean("userController");//通常情况下是小驼峰(将加注解的类的类名首字母小写)就可以获取到bean对象
        //3.使用bean
        userController.sayHi("张三");
    }
}

当使用id获取带注解的bean时:

关于类注解的bean的命名规则:

通常bean使用的都是标准的大驼峰命名:

  • 若bean的命名为第一个字母大写,第二个字母小写,那么读取时将bean的名称首字母小写
  • 若bean的命名为第一个字母和第二个字母都大写,那么读取时为原bean名
  • 若bean的命名为第一个字母和第二个字母都小写,那么读取时为原bean名(一般不存在)。

查看源码(ctrl + 鼠标左键变成手形,点击进入):

5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象5-Spring更简单的读取和存储对象

②@Service(服务存储)

@Service //将当前对象存储到Spring中
public class UserService {
    public void sayHi(String name){
        System.out.println("Hi," + name);
    }
}

③@Repository(仓库存储)

@Repository //将当前对象存储到Spring中
public class UserRepository {
    public void sayHi(String name){
        System.out.println("Hi," + name);
    }
}

④@Component(组件存储)

@Component //将当前对象存储到Spring中
public class UserComponent {
    public void sayHi(String name){
        System.out.println("Hi," + name);
    }
}

⑤@Configuration(配置存储)

@Configuration //将当前对象存储到Spring中
public class UserConfiguration {
    public void sayHi(String name){
        System.out.println("Hi," + name);
    }
}

PS:为什么要这么多类注解?

①5大类注解之间的关系:

查看源码:

5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象

 结论:

@Controller,@Service,@Repository,@Configuration这4个注解都是依靠@Component注解来实现的,因此@Component注解是其他4个注解的父类。

那为啥还要其他4个呢?

②程序的工程分层-调用流程:

一个项目中后端接口最少有这4个目录,方便大型项目中类的分类,查找,维护:

让程序员看到类注解后,能直接了解当前类的用途,让逻辑条理更加清晰;

也方便项目的人员分工,每人只针对一部分即可。

而若都是@Component注解,则不会直观地了解到类的用途。

so~类注解由1个变5个,使得整个代码的语义更加直观!

5-Spring更简单的读取和存储对象

  • @Controller:业务逻辑层/控制器层,和前端请求打交道,验证前端的有效性;
  • @Service:服务层,组织数据调用相应的接口,不做具体的业务;
  • @Repository:数据持久层/仓库(不同的叫法:dao/repository),和数据打交道,执行具体的CRUD操作;
  • @Configuration:配置层,存放所有的配置信息。

还可能会有更多分层,如有实体层model,工具层utils,数据持久层(MyBatis中)mapper等。

1.2.2.方法注解(添加到某个方法上,将当前方法返回的对象存储到Spring中):@Bean

①方法注解要配合类注解一起使用,才能将对象正常存储到Spring中。(主要是为了考虑性能的问题) 默认读取bean的名称为方法名。

@Component
public class UserBeans {
    @Bean
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPassword("123");
        return user;
    }
}

②重命名Bean

方法名主要体现业务性,多为动词;读取bean名称多为名词。若默认二者相等会比较奇怪。

那么可以通过在@Bean注解中设置name属性给Bean对象进行重命名操作:

@Component
public class UserBeans {
    @Bean(name = {"user1"})
    public User getUser() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPassword("123");
        return user;
    }
}

注:

1).这个重命名的name其实是一个数组,一个bean可以有多个名字。

含有"{ }"的写法表示给当前对象起一个或多个别名。

@Bean(name = {"user1"})
@Bean(name = {"user1", "user2"})

并且name = { } 可以省略。

@Bean("user1", "user2")

不含有"{ }"的写法表示给当前对象起一个别名。

@Bean(name = "user1")

2).当@Bean注解重命名之后就不能使用方法名来读取bean了。

2.获取Bean对象(对象装配/对象注入)

获取bean对象是把对象取出来放到某个类中。实现方法有3种。5大类注解不能省略(存了才能取)。

2.1.属性注入:是使用@Autowired(自动写入)注解实现的

例:将Service类注入到Controller类中:

Service类的实现代码如下:

import com.model.User;
import org.springframework.stereotype.Service;

@Service
public class UserService {
    /**
     * 根据id获取用户数据
     * @param id
     * @return
     */
    public User getUserById(Integer id) {
        //伪代码,不连接数据库
        User user = new User();
        user.setId(id);
        user.setName("唐僧");
        user.setPassword("123456");
        return user;
    }
}

Controller类的实现代码如下:

import com.beans.service.UserService;
import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController {
    //1.属性注入:先定义一个属性,再把对象注入给属性
    @Autowired
    private UserService userService;

    public User getUserById(Integer id) {
        return userService.getUserById(id);
    }
}

获取Controller中的getUserById方法:

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

public class App {
    public static void main(String[] args) {
        //1.获取Spring上下文
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        //2.得到bean
        UserController userController = context.getBean(UserController.class);
        //3.使用bean
        System.out.println(userController.getUserById(10));
    }
}

5-Spring更简单的读取和存储对象

2.2.构造方法注入:是在类的构造方法中实现注入

如果当前类只有一个构造方法,则@Autowired注解可以省略;

如果当前类有多个构造方法,则@Autowired注解不可以省略。

import com.beans.service.UserService;
import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller 
public class UserController2 {
    private UserService userService;

    //2.构造方法注入
    @Autowired
    public UserController2(UserService userService) {
        this.userService = userService;
    }

    public UserController2(UserService userService, Integer id) {
        this.userService = userService;
    }

    public User getUserById(Integer id) {
        return userService.getUserById(id);
    }
}

2.3.Setter注入:和属性的Setter方法实现类似,只不过在设置set方法时需要加上@Autowired注解

import com.beans.service.UserService;
import com.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller
public class UserController3 {
    private UserService userService;

    //3.Setter注入
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }

    public User getUserById(Integer id) {
        return userService.getUserById(id);
    }
}

PS:(经典面试题)属性注入,构造方法注入和Setter注入的异同分析?

都可以将一个对象注入到当前的类当中。

属性注入(差):

  • 优点:简洁,使用方便。官方实际还是用属性注入多些
  • 缺点:不通用,只能用于IoC容器,非IoC容器不可用(使用的时候会出现NPE(空指针异常))。

构造方法注入(好):

  • 优点:通用性强;且在使用之前一定能保证注入的类不为空(能保证在调用对象之前,此对象一定是存在的)是Spring后期推荐的注入方式
  • 缺点:可能存在传递多个参数来实现构造方法的初始化,如果有多个注入会显得代码比较臃肿,但出现这种情况是程序员自身的问题,他需要反思当前类是否符合程序的单一职责的设计模式。

Setter注入(中):

  • 优点:是Spring早期版本推荐的注入方式,比属性注入适用性好,无论是IoC容器还是非IoC容器都可以使用。
  • 缺点:通用性不如构造方法注入,所有Spring版本已经推荐使用构造方法注入的方式来进行类注入了。

2.4.另一种注入关键字:@Resource

在进行对象注入时,除了可以使用@Autowired关键字之外,还可以使用@Resource进行注入。

2.4.1.属性注入:

import com.beans.service.UserService;
import com.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller
public class UserController4 {
    @Resource //引入一个资源到当前类
    private UserService userService;

    public User getUserById(Integer id){
        return userService.getUserById(id);
    }
}

2.4.2.Setter注入:

import com.beans.service.UserService;
import com.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller 
public class UserController5 {
    private UserService userService;

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

    public User getUserById(Integer id){
        return userService.getUserById(id);
    }
}

PS:(经典面试题)@Autowired和@Resource的区别?

①出身不同:

  • @Autowired是Spring框架提供的实现;
  • 而@Resource是JDK提供的实现。

②支持的参数设置不同:

  • @Autowired只支持required设置;

5-Spring更简单的读取和存储对象

@Autowired注解源码实现

5-Spring更简单的读取和存储对象

  • 而@Resource支持更多的参数设置,如name设置,根据名称获取bean。

5-Spring更简单的读取和存储对象

 @Resource注解源码实现5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象

5-Spring更简单的读取和存储对象③支持的注入类型不同:

  • @Autowired支持属性注入,构造方法注入和Setter注入;
  • 而@Resource只支持属性注入和Setter注入。

④获取注入一个对象时的机制不同:

  • @Autowired默认先按Type进行匹配,如果找到多个bean,则又会按照组件id方式进行匹配(需要@Qualifier("name")配合);
  • 而@Resource默认按照组件id自动注入,如果按照默认组件id找不到bean时,再按照类型去匹配。

2.5.同一类型多个@Bean报错

import com.model.User;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

@Component
public class UserBeans {
    @Bean(name = {"user1"})
    public User getUser1() {
        User user = new User();
        user.setId(1);
        user.setName("张三");
        user.setPassword("123");
        return user;
    }

    @Bean(name = "user2")
    public User getUser2() {
        User user = new User();
        user.setId(2);
        user.setName("李四");
        user.setPassword("456");
        return user;
    }
}
import com.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller
public class UserController6 {
    @Resource
    private User user;

    public void sayHi(){
        System.out.println(user);
    }
}
import com.beans.controller.UserController6;
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");
        UserController6 controller6 = context.getBean(UserController6.class);
        controller6.sayHi();
    }
}

5-Spring更简单的读取和存储对象

一个类型被注册到Spring多次时,程序运行会出现异常报错:非唯一的Bean对象。

处理方法:

2.5.1.使用正确的bean name来获取(有限制,不用于大规模使用)

import com.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller
public class UserController6 {
    @Resource
    private User user2;

    public void sayHi(){
        System.out.println(user2);
    }
}

5-Spring更简单的读取和存储对象

2.5.2.使用@Resource注解设置name属性(最简单)(@Autowired只有一个参数,没有name属性)

import com.model.User;
import org.springframework.stereotype.Controller;
import javax.annotation.Resource;

@Controller
public class UserController6 {
    @Resource(name = "user1")
    private User user;

    public void sayHi(){
        System.out.println(user);
    }
}

5-Spring更简单的读取和存储对象

2.5.3.使用@Autowired + @Qualifier

5-Spring更简单的读取和存储对象5-Spring更简单的读取和存储对象

@Qualifier只有一个属性,做筛选功能。

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

@Controller
public class UserController6 {
    @Autowired
    @Qualifier(value = "user2")
    private User user;

    public void sayHi(){
        System.out.println(user);
    }
}

5-Spring更简单的读取和存储对象

 其中:

@Qualifier(value = "user2")

也可以省略"value =",写为:

@Qualifier("user2")

 文章来源地址https://www.toymoban.com/news/detail-424684.html

到了这里,关于5-Spring更简单的读取和存储对象的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Spring】更简单的读取和存储对象,五大类注解

    经过前面的学习,我们已经可以实现基本的 Spring 读取和存储对象的操作了,但在操作的过程中我们发现读取和存储对象并没有想象中的那么 “简单”,所以接下来我们要学习更加简单的操作 Bean 对象的方法 在 Spring 中想要 更简单的存储和读取对象的核心是使用注解 ,也就

    2024年02月15日
    浏览(26)
  • 【JavaEE进阶】Spring 更简单的读取和存储对象

    配置扫描路径是使用注解之前的前置工作,是非常重要的,是必须的操作项.只有被配置的包下的所有类,添加了注解才能被正确的识别并保存到 Spring 中. 首先创建一个Spring项目.创建好后,第一步就是配置扫描路径:在 resources 目录中创建一个 spring-config.xml 文件.然后在 spring-config.

    2024年02月12日
    浏览(31)
  • 【Spring框架全系列】Spring更简单的读取和存储对象

    📬📬哈喽,大家好,我是小浪。上篇博客我们介绍了如何创建一个spring项目,并且如何的存、取对象,介绍了相关方法,那么本篇博客将接着上篇博客的内容介绍如何更加简单的读取和存储对象。 🌃在 Spring 中想要更简单的存储和读取对象的核⼼是使⽤注解,也就是我们接

    2024年02月05日
    浏览(31)
  • JavaEE 突击 5 - Spring 更简单的读取和存储对象(2)

    大家新年快乐 , 祝大家新的一年如图 这个专栏给大家介绍一下 Java 家族的核心产品 - SSM 框架 JavaEE 进阶专栏 Java 语言能走到现在 , 仍然屹立不衰的原因 , 有一部分就是因为 SSM 框架的存在 接下来 , 博主会带大家了解一下 Spring、Spring Boot、Spring MVC、MyBatis 相关知识点 并且带领

    2024年02月19日
    浏览(42)
  • 3. Spring 更简单的读取和存储对象(五大类注解 & 方法注解)

    目录 1. 存储 Bean 对象 1.1 配置扫描路径 1.2 添加注解存储 Bean 对象 1.2.1 @Controller(控制器存储) 1.2.2 @Service(服务存储) 1.2.3 @Repository(仓库存储) 1.2.4 @Component(组件存储) 1.2.5 @Configuration(配置存储) 1.3 使用多个类注解的原因 1.3.1 五大注解之间的关系 1.3.1 Bean 的命名

    2024年02月15日
    浏览(24)
  • Spring使用注解存储和读取对象

    之前我们存储Bean时,需要在spring-config.xml中添加bean注册才行,这样的方式并不简单。我们要想 更简单的存储和读取对象的核心是使用注解 1.使用类注解(五大类注解): @Controller:控制器,验证用户请求的数据正确性(安保系统) @Service:服务层,编排和调度具体执行方法的(客服

    2023年04月19日
    浏览(34)
  • 【Spring】使用注解读取和存储Bean对象

     哈喽,哈喽,大家好~ 我是你们的老朋友: 保护小周ღ    谈起Java 圈子里的框架,最年长最耀眼的莫过于 Spring 框架啦,本期给大家带来的是:  将对象存储到 Spring 中、Bean 对象的命名规则、从Spring 中获取bean 对象、注入的、@Autowired 与 @Resource 的区别、解决@Bean 方

    2024年02月13日
    浏览(37)
  • Spring中Bean对象的存储与读取

    在项目的 pom.xml 中添加 Spring 支持 如何选定版本环境:打开官网,点击github图标 jdk8最后一个Spring版本是5.3.x,Spring6.0.x最低需要jdk17 版本冲突问题Maven自己处理 version : 可以选择带有 RELEASE结尾或者纯数字结尾,这样的版本更稳定 项目下创建一个main方法的启动类 存储 Bean 之前

    2024年01月24日
    浏览(28)
  • 【Spring】(三)Spring 使用注解存储和读取 Bean对象

    前面的文章详细的介绍了 Spring 对象的创建,以及对 Bean 对象的存取操作,但是通过配置文件注册 Bean 对象以及使用 ApplicationContext 或 BeanFactory 的方式获取 Bean 对象的操作就显得格外的复杂。因此,本文主要就是详细介绍了一种更加简单的方式来实现对 Bean 对象更加简单的储

    2024年02月14日
    浏览(28)
  • 从 Spring 的创建到 Bean 对象的存储、读取

    目录 创建 Spring 项目: 1.创建一个 Maven 项目:  2.添加 Spring 框架支持: 3.配置资源文件: 4.添加启动类: Bean 对象的使用: 1.存储 Bean 对象: 1.1 创建 Bean: 1.2 存储 Bean 到容器内: 2.获取 Bean 对象: 2.1 创建 Spring 上下文: 2.2 获取指定 Bean 对象: ApplicationContext 和 BeanFactor

    2024年02月06日
    浏览(33)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包