Spring五大类注解读取存储Bean对象的方法
作者:bug?郭 发布时间:2023-11-09 22:07:07
前情提要
我们上节内容学习了如何创建\注册\读取bean
我们发现bean
对象操作十分的繁琐!
所以我们这个章节,就带大家来了解更加简单的bean
操作,通过Spring
下的注解来实现!
配置spring-config文件
我们之前注册
bean
是通过在xml
配置文件中,通过键值对的方式注册bean
对象!
显然这种方式很麻烦,注册一个对象,就要添加一项!
有没有什么好的方式可以让spring
直接去注册对象!yes!
我们可以直接在配置文件配置好 spring
下你要注册对象的包时那个!
当spring
启动后,spring
就会将bean
对象自动注册!
spring-config
配置文件
<?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">
<!--在com包下扫描bean注册-->
<content:component-scan base-package="com"></content:component-scan>
</beans>
当然只有一个配置文件显然不够嘛!
我们如何知道我们代码中的对象是bean
对象捏?
这就要引入spring
五大注解概念了!
我们通过在我们创建好的对象上面添加注解的方式,就是告诉spring
这个对象需要注册到容器中!
类注解和方法注解
类注解:
@Controller@Service@Repository@Component@Configuration
方法注解:
@Bean
我们可以通过上述两种注解将对象存储到Spring
中!
@Controller(控制器存储)
使用@Controller
注解存储bean
package com;
import org.springframework.stereotype.Controller;
@Controller //通过Controller注解存储bean对象
public class UserController {
public void sayHi(){
System.out.println("hello Controller注解!");;
}
}
我们通过在UserController
类上加上spring
类注解,即可完成注册对象!
在启动类中读取bean
对象即可!
//启动类
public class app{
public static void main(String[] args) {
//1.获取上下文对象
ApplicationContext context =
new ClassPathXmlApplicationContext("spring-config.xml");
//读取bean对象!
UserController userController =
(UserController) context.getBean("userController");
//使用
userController.sayHi();
}
}
如果我们的需要注册的bean
对象不在扫描包下,是否又能注册成功呢?
我们在新建一个controller
包在其下创建TestController
类,并且通过@Controller
注册到Spring
中!
package controller;
import org.springframework.stereotype.Controller;
@Controller //注册到Spring中!
public class TestController {
public void sayHi(){
System.out.println("该bean不在扫描的包下");
}
}
然后我们通过ApplicationContext
上下文对象读取bean
可以看到出现异常未找到名为textController
的bean
对象!
结论:只有在扫描包下的类才能被Spring
注册
@Service(服务存储)
注册bean
package com;
import org.springframework.stereotype.Service;
@Service // @Service 注解注册对象!
public class UserService {
public void sayHi(){
System.out.println("Hello Service注解!");
}
}
读取bean
@Configuration(配置存储)
package com;
import org.springframework.context.annotation.Configuration;
@Configuration //Configuration注解注册bean对象
public class UserConfiguration {
public void sayHi(){
System.out.println("Hello Configuration注解!");
}
}
@Repository(仓库存储)
package com;
import org.springframework.stereotype.Repository;
@Repository //@Respository 注解注册对象
public class UserRepository {
public void sayHi(){
System.out.println("Hello Respository注解!");
}
}
@Component(组件存储)
package com;
import org.springframework.stereotype.Component;
@Component //Component注解注册对象!
public class UserComponent {
public void sayHi(){
System.out.println("Hello Component注解!");
}
}
5大类注解联系
可以看到这5大类注解使用方式一样,都可以对对象进行注册!
而且注册的方式都一样,既然如此为何还需要5个注解呢?
我们联系实际生活中的车牌号,我们虽然车牌号的功能都是一样,但是不同地区都有自己的车牌号!我们通过车牌号就可以分辨出这车来自哪里!
而这里5大类注解作用也是如此,我们通过类注解,可以知道当前类的用途!
例如;
@Controller
:表示业务逻辑层@Service
:服务层@Repository
:持久层@Configuration
:配置层
程序的工程分层,调用流程如下:
我们拿去银行办业务做类比:
@Controller
层就是保安,先要进行检查验证,然后到达Service
服务厅询问业务,不同的业务来到Repository
,不同的窗口,然后进行相应的工作人员办理业务!
类注解之前联系:
可以看到其他4个注解都是Component
注解的子类!
Spring给Bean命名规则
我们可以看到我们刚刚读取
bean
对象时,我们并不知道bean
对象注册的id
而是直接通过userController
读取!
难道说Spring注册bean对象id
为类名首字母小写,直接就小驼峰?
我们查看Spring
源码验证!
我们顺藤摸瓜下方就是Spring
对Bean对象进行命名的方法!
public static String decapitalize(String name) {
if (name == null || name.length() == 0) {
return name;
}
if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
Character.isUpperCase(name.charAt(0))){
return name;
}
char chars[] = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
可以看到我们这里bean
对象的id
命名规则如下:
对象类类名一般采用大驼峰的形式也就是单词第一个字母大小,所以Spring
直接bean
对象改为小驼峰,`第一个字母分成小写!对象类类名不规范,不是大驼峰,第二个字母和第一个字母都是大小!Spring
直接将bean对象命名为类名!
我们进行验证:
方法注解@Bean
我们了解了5大类注解可以进行对象注册,我们使用方法注解进行对象注册!
注意: 方法注解要和类注解配合使用!
方法注解进行对象注册
//User类
public class User {
private String name;
private int id;
public User(String name, int id) {
this.name = name;
this.id = id;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", id=" + id +
'}';
}
}
//Users类
@Component
public class Users {
@Bean
public User user(){
return new User("java",666);
}
}
可以看到@Bean
注解适用于返回值返回对象的方法中!
重命名Bean
我们既然可以通过五大类注解进行对象注入!那为何还要多此一举在方法上加上
@Bean
方法注解呢?
我们可以通过@Bean
方法注解给bean
对象重命名,可以直接设置名字!
通过
name={"rename1", "rename2"...}
可以重命名多个!
@Component
public class Users {
@Bean(name = {"user1"})
public User user(){
return new User("java",666);
}
}
能否通过之前Spring
给我们设置的名字访问? 不能
@Bean(name={"user1","user2"})
重命名多个!
我们也可以将name
省略@Bean({"user1"})
获取Bean对象(对象装配)
这里可能听了有点迷,啥玩意对象装配,其实就是获取对象!
我们将对象注册到Spring
容器下,我们要读取将对象取出放入到某个类中,这就是对象装配,也叫对象注入!
实现对象装配的3种方法
属性注入
构造方法注入
Setter注入
下面我们来演示一下这3种注入方式
我们按照实际开发将Service
层的类注入到Controller
层的类中!
属性注入
我们通过@Autowired
实现属性注入service
层类代码
@Service
public class UserService {
public User getUser(){
return new User("Mysql",666);
}
}
controller
层类代码
通过属性注入将service
层代码注入到这
@Controller
public class UserController {
//属性注入
@Autowired
private UserService userService;
public User getUser(){
return userService.getUser();
}
}
运行结果:
构造方法注入
我们还是通过@Autowired
注解注入
@Controller
public class UserController {
private UserService userService;
//构造方法注入
@Autowired
public UserController(UserService userService){
this.userService = userService;
}
public User getUser(){
return userService.getUser();
}
}
Setter注入
@Controller
public class UserController {
//Setter注入
private UserService userService;
@Autowired
public void setUserService(UserService userService){
this.userService = userService;
}
public User getUser(){
return userService.getUser();
}
}
三种注入方式对比
属性注入简洁,使用方便! 缺点只能适用于IoC容器,在非IoC容器不适用,并且属性注入只有在是使用的时候才会出现空指针异常(NPE)
构造方法注入现在官方推荐注入方式! 缺点 如果注入多个对象,就会使得代码臃肿,不过这就是程序员的问题了,不符合程序设计的单一职责的设计模式,优点通用性强,在使用前一定可以保证注入的类不为空!
Setter方式是Spring前期推荐的注入方式,通用性不如构造方法注入,现在已经认准构造方法注入!
在进行类注入时,我们还可以通过@Resource
注解进行注入!
我们只需要将@Autowired
注解换成@Resource
即可!
@Autowired
和@Resource
区别
出身不同:
@Autowired
注解是Spring
提供的,@Resource
是来自JDK
下的注解使用设置的参数不同:相比
@Autowired
注解,@Resource
注解 支持更多的参数设置 例如name
设置,根据name
获取对象
注入同一类型多个Bean对象
我们在Users
类中注册了2个相同类型的Bean
对象!
@Component
public class Users {
@Bean(name = "user1")
public User user1(){
User user = new User("java",666);
return user;
}
@Bean(name = "user2")
public User user2(){
User user = new User("MySQL",666);
return user;
}
}
当我们直接注入到Controller
类中!
@Controller
public class UserController {
@Resource
private User user;
public User getUser(){
return user;
}
}
因为我们在Spring
中注册了2个相同类型的User
对象,所以进行对象装配时,也需要通过name
属性进行声明你要装配的对象名!
@Controller
public class UserController {
@Resource(name = "user2")
private User user;
public User getUser(){
return user;
}
}
注意:
@Resource
注解才提供了name
属性,如果用@Autowried
需要加上@Qualifier
注解定义名称
@Controller
public class UserController {
// @Resource(name = "user2")
@Autowired
@Qualifier(value = "user1")
private User user;
public User getUser(){
return user;
}
}
来源:https://blog.csdn.net/weixin_52345071/article/details/126664841
猜你喜欢
- 介绍超级管理员:系统管理、用户管理、网点管理、运输点管理、快递员管理、网点申请管理(审核)、报价管理(时效报价)等。普通用户:注册登录、个人
- 1、什么是 ThreadLocal:ThreadLocal,即线程本地变量,如果你创建了一个变量,那么访问这个变量的每个线程都会有这个变量的
- [LeetCode] 131.Palindrome Partitioning 拆分回文串Given a string s, par
- 直接用英文逗号分隔就可以了,比如:inerface IHello { String sayHello(String name);
- FrameLayout 在这个布局中,所有的子元素都不能被指定放置的位置,他们统统防御这块区域的左上角, 并且后面的子元素直接覆盖在前面的子
- 现在的项目基本上都是java web项目,所以导入jar包会出现问题,主要介绍一下java项目与javaweb项目的区别:java项目:在c
- Java Function的使用一、方法介绍表示接受一个参数并产生结果的函数。参数类型 T - 函数输入的类型R - 函数的结果类型方法介绍
- 引言备忘录模式经常可以遇到,譬如下面这些场景:浏览器回退:浏览器一般有浏览记录,当我们在一个网页上点击几次链接之后,可在左上角点击左箭头回退
- 一、概述现在大多数的电商APP的详情页长得几乎都差不多,几乎都是上面一个商品的图片,当你滑动的时候,会有Tab悬浮在上面,这样做用户体验确实
- 一、判断语句最常用的顺序结构只能顺序执行,并不能进行判断和选择。于是便有了下面两种分支结构if语句switch语句1. if语句一个if语句
- 一般都在windows下开发的,现在部署到linux下:1,将项目达成war包(用eclipse,项目右键-->Export-->
- 简介使用配置类和注解代替web.xml和SpringMVC配置文件的功能在Servlet3.0环境中,容器会在类路径中查找实现javax.s
- Java 数据库连接池详解数据库连接池的原理是:连接池基本的思想是在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库
- 无论是我们在使用word还是记事本,系统都会为我们提供撤销的功能,这几乎是人人都会使用到的功能,而在我们实际开发中,会不会存在一个很复杂的对
- 前言目前Flutter三大主流状态管理框架分别是provider、flutter_bloc、getx,三大状态管理框架各有优劣,本篇文章将介
- @Order控制配置类/AOP/方法/字段的加载顺序1.AOP加载顺序 @Component &nbs
- 一. 线性表中的顺序表线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构,常见
- spring.activemq.pool.enabled=false时,每发送一条数据都需要创建一个连接,这样会出现频繁创建和销毁连接的场景
- 一个是新浪微博,腾讯微博的分享按钮,一个是他们的绑定情况(其实就是是否授权)。点击微博分享中新浪或腾讯按钮,就进行相应的授权(若没授权),显
- 定义与结构 备忘录(Memento)模式又称标记(Token)模式。GOF给备忘录模式的定义为:在不破坏