【Spring】Spring更简单的读取和存储对象---使用注解

news/2024/11/7 13:43:59/

目录

1.Spring的存储对象------存储Bean对象

1.前置工作,配置扫描路径

2.添加注解存储Bean对象

1.@Controller(控制器存储)

2.@service(服务存储)

3.@Repository(仓库存储)

4.@Component(组件存储)

5.@Configuration(配置存储)

3.为什么这么多类注解

1.类注解之间的关系

4.方法注解@Bean

1.方法注解要搭配类注解使用

2.重命名Bean

2.Spring的读取------获取Bean对象(对象装配)

1.属性注入

2.构造方法注入

3.Setter注入

4.三种注入方法的优缺点

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

@Resource和@Autowired的区别

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

1.现象

 2.报错处理

使⽤ @Resource(name="xxx")

使⽤ @Qualifier


在上一篇文章中实现了基本的Spring读取和存储对象。但在操作的过程中我们发现读取和存储对象并没有想象中的那么“简单”。

所以接下来我们要讲解更加简单的操作 Bean 对象的⽅法。其核心就是,使用注解

1.Spring的存储对象------存储Bean对象

之前我们存储 Bean 时,需要在 spring-config 中添加⼀⾏ bean 注册内容才⾏,如下图所示:

⽽现在我们只需要⼀个注解就可以替代之前要写⼀⾏配置的尴尬了。

类注解规则:1.类名前两位均为大写时,返回自身name

                  2.否则,首字母小写

1.前置工作,配置扫描路径

想要将对象成功的存储到 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"><content:component-scan base-package="org.example"></content:component-scan>
</beans>

其中标红的一行为注册扫描的包,如下图所示:

注意:即使添加了注解,如果不是在配置的扫描包下的类对象,也是不能被存储到Spring中的。

2.添加注解存储Bean对象

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

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

2. ⽅法注解:@Bean。

1.@Controller(控制器存储)

使用@Controller存储Bean的代码如下所示:

@Controller
public class UserController {public void sayHi(){System.out.println("hi,userController~");}
}

在App中读取上面的UserController对象:

public class App {public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");UserController userController=(UserController) context.getBean("userController");userController.sayHi();}
}

运行结果:

这里并没有在spring-config.xml中添加id,但是依旧能正确运行。是因为@Controller注解自动的起到了一个id的作用。作用与如下代码一致:

    <bean id="userController" class="org.example.UserController"></bean>

2.@service(服务存储)

使用@service存储Bean的代码如下所示:

@Service
public class UserService {public void doService(){System.out.println("doService");}
}

在App中读取上面的UserService对象:

public class App {public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");UserService userService=(UserService) context.getBean("userService");userService.doService();}
}

3.@Repository(仓库存储)

使用@Repository存储Bean的代码如下所示:

@Repository
public class UserRepository {public void sayHi(){System.out.println("hi,repository");}
}

在App中读取上面的UserRepository对象:

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

4.@Component(组件存储)

使用@Component存储Bean的代码如下所示:

@Component
public class UserComponent {public void sayHi(){System.out.println("hi,component");}
}

在App中读取上面的UserComponent对象:

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

5.@Configuration(配置存储)

使用@Configuration存储Bean的代码如下所示:

@Configuration
public class UserConfiguration {public void doConfiguration(){System.out.println("hi,Configuration");}
}

在App中读取上面的UserConfiguration对象:

public class App {public static void main(String[] args) {ApplicationContext context=new ClassPathXmlApplicationContext("spring-config.xml");UserConfiguration userConfiguration=(UserConfiguration) context.getBean("userConfiguration");userConfiguration.doConfiguration();}
}

3.为什么这么多类注解

由以上对每个注解的介绍,可以看出,这些注解的功能都是一样的,那么为什么需要这么多类注解呢?

其目的就是让程序员看到类注解之后,就能直接了解当前类的用途。

@Controller:表示业务逻辑层,通常是指程序的入口,比如:参数校验,参数类型转换等前置处理工作。

@Service:服务层,一般写业务代码,服务编排,比如:调用DB,调用第三方接口。

@Repository:持久层,仓库,通常指DB操作相关的代码。(通常放在DAO层下面)

@Component:其它的对象。

@Configuration:配置层。

程序的工程分层,调用流程如下:

1.类注解之间的关系

查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现:

 其实这些注解⾥⾯都有⼀个注解 @Component,说明它们本身就是属于 @Component 的“子类”。

4.方法注解@Bean

1.方法注解要搭配类注解使用

在 Spring 框架的设计中,⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中,如下代码所示:

@Configuration
public class BeanConfig {@Beanpublic User user() {User user=new User();user.setName("温温");user.setAge(18);return user;}
}

注意:@Bean对应生产的bean名称是方法名

2.重命名Bean

可以通过设置name属性给Bean对象进行重命名操作,如下对象所示:

@Configuration
public class BeanConfig {@Bean(name={"wen","user"})public User user() {User user=new User();user.setName("温温");user.setAge(18);return user;}
}

此时使用wen和user都可以获取到User对象了:

        User user=(User) context.getBean("wen");System.out.println(user.getName());

2.Spring的读取------获取Bean对象(对象装配)

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

对象装配(对象注⼊)的实现⽅法以下 3 种:

1. 属性注⼊

2. 构造⽅法注⼊

3. Setter 注⼊

1.属性注入

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

Service类的代码如下:

@Service
public class UserService {public void doService(){System.out.println("doService");}
}

Controller类的实现代码如下:

@Controller
public class UserController {@Autowiredprivate UserService userService;public void sayHi(){userService.doService();System.out.println("hi,userController~");}
}

最终结果如下:

2.构造方法注入

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

@Controller
public class UserController2 {private UserService us;public UserController2(UserService us) {this.us = us;}public void sayHi(){us.doService();System.out.println("hi,userController~");}
}

注意:1.如果只有一个构造方法,那么@Autowired可以省略

           2.如果有多个构造方法,那么需要添加上@Autowired来明确指定到底使用哪个构造方法,否则程序会报错。

3.Setter注入

Setter 注⼊和属性的 Setter ⽅法实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注

解,如下代码所示:

@Controller
public class UserController1 {private UserService us;@Autowiredpublic void setUs(UserService us) {this.us = us;}public void sayHi(){us.doService();System.out.println("hi,userController~");}
}

4.三种注入方法的优缺点

优点缺点
属性注入简介,使用方便
1.是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只有在使⽤的时候才会出现 NPE(空指针异常)
2.不能注入一个final修饰的属性
构造方法注入(
 Spring 推荐

1.可以注入final修饰的属性

2.注入的对象不会被修改

3.依赖对象在使用前一定会被完全初始化

4.通用性好

如果有多个注⼊会显得⽐较臃肿,但出现这种情况你应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式了,
setter注入
方便再类实例之后,重新对该对象进行配置或注入
1.不能注入一个final修饰的属性
2.注入对象可能会被改变,因为setter方法可能会被多次调用,就有被修改的风险

补充:final修饰的属性,需要具备下列两个条件之一:

1.初始化赋值

2.构造函数赋值

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

在进⾏类注⼊时,除了可以使⽤ @Autowired 关键字之外,我们还可以使⽤ @Resource 进⾏注⼊,如下代码所示:

@Controller
public class UserController3 {@Resourceprivate UserService us;public void sayHi(){us.doService();System.out.println("hi,userController~");}
}

@Resource和@Autowired的区别

  • 出身不同:@Autowired来自于Spring,⽽ @Resource 来⾃于 JDK 的注解;
  • 使⽤时设置的参数不同:相⽐于 @Autowired 来说,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。
  • @Autowired 可⽤于 Setter 注⼊、构造函数注⼊和属性注⼊,⽽ @Resource 只能⽤于 Setter 注⼊和属性注⼊,不能⽤于构造函数注⼊。

补充:

@Autowired

根据类型来获取bean,如果同一个类型的bean只有一个,直接注入成功

如果同一个类型的bean有多个,以名称匹配,注入相同名称的bean

如果没有名称相同的,就报错

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

1.现象

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

@Component
public class Users {@Beanpublic User user1() {User user = new User();user.setId(1);user.setName("Java");return user;}@Beanpublic User user2() {User user = new User();user.setId(2);user.setName("MySQL");return user;}
}

在另一个类中获取User对象:

@Controller
public class UserController4 {// 注⼊@Resourceprivate User user;public User getUser() {return user;}
}

报错了,报错原因为:非唯一的Bean对象

 2.报错处理

解决同⼀个类型,多个 bean 的解决⽅案有以下两个:

  • 使⽤ @Resource(name="user1") 定义。
  • 使⽤ @Qualifier 注解定义名称。

使⽤ @Resource(name="xxx")

使⽤ @Qualifier


http://www.ppmy.cn/news/921549.html

相关文章

关于HDMI2.1的一些常见问题答疑

HDMI2.1新规范已经发布,它能够处理更高的刷新率和分辨率,如8K @ 60Hz和4K @ 120Hz,但这只是冰山一角。 动态HDR将确保客户不必自己调整每个游戏或电影。 HDMI 2.1还在电视中引入了可变刷新率,称为“游戏模式VRR”;例如,如果微软的Scorpio硬件支持HDMI 2.1,这可能会在控制…

让Mplayer或SMplayer成为网络电视客户端(安装Mplayer以Fedora为例)

PPLive、PPS、UUSee等网络电视已经成为了Windows操作系统必备的家居旅游&#xff0c;网上娱乐的必备工具。在Windows上我们能看许许多多的节目。但是&#xff0c;我们现在说的不是Windows上的这些常用的&#xff0c;而是多平台的&#xff0c;比如Linux等等。让这些平台同时能播…

你即将拥有HDMI2.1,纯光纤HDMI最高支持72Gbps试用体验

目前市场中各类4K HDR设备可谓百花齐放,而且4K UHD蓝光片源也高达数百部之多,众多影音发烧友都选择符合HDMI 2.0标准规格的碟机和投影机,但是很多人在升级投影机的时候发现原有的HDMI 1.4线不能点亮新购入的4K投影机了,选择一条品质有保障信号可以稳定传输HDMI 2.0的HDMI线…

[个人笔记] 交换机日常巡检笔记

数据通信 - 运维篇 第二章 交换机日常巡检笔记 数据通信 - 运维篇系列文章回顾交换机日常巡检笔记参考链接 系列文章回顾 第一章 交换机性能参数计算公式 交换机日常巡检笔记 display interface相关 ### Huawei S系列交换机 ### H3C S系列交换机 display interface # 查看…

【电子学会】2023年05月图形化三级 -- 绘制多彩五角星

绘制多彩五角星 1. 准备工作 &#xff08;1&#xff09;选择背景stars、角色Pencil&#xff1b; &#xff08;2&#xff09;将角色Penci的中心点设为笔尖。 2. 功能实现 &#xff08;1&#xff09;将画笔粗细设为3&#xff0c;画笔的颜色和初始位置自定义&#xff0c;绘制边…

戏说BIOS之Beep

戏说BIOS之Beep 1. Introduction 大凡用过电脑的朋友都应该听到过BIOS的报警声&#xff0c;有时 PC开机的时候就会听到嘀的一声&#xff0c;有过修理PC经验的话就更清楚了“一短内存刷新失败&#xff0c;二短内存校验错误&#xff0c;一长三短内存错误&#xff0c;一长八短显示…

关于SYS/BIOS

1.什么是SYS/BIOS SYS/BIOS是一个可拓展的实时内核。用于实时调度和同步的应用程序或实时的设备。SYS/BIOS提供了抢占式多线程&#xff0c;硬件抽象&#xff0c;实时分析和配置工具。SYS/BIOS的设计是为了最大限度地减少对内存和CPU的要求。 SYS/BIOS的优点&#xff1a; &am…

SMBIOS和DMI

了解SMBIOS和DMI 1.SMBIOS 系统管理BIOS (System Management BIOS ) 是主板或者系统制造厂商以标准格式显示产品信息所遵循的统一规范。每个主板厂商或者OEM厂商所生产的电脑&#xff0c;在出厂的时候都会按照smbios标准将信息写入到bios中。这些信息包括BIOS信息、系统信息、…