Spring添加注解读取和存储对象

5大注解

@Controller 控制器

@Service 服务

@Repository 仓库

@Componet 组件

@Configuration 配置

五大类注解的使用

//他们都是放在同一个目录下,不同的类中 只不过这里粘贴到一起

//控制器
@Controller
public class UserController {
    public void SayHello(){
        System.out.println("Hello");
    }
}

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

//仓库
@Repository
public class UserRepository {
    public void DoRepository(){
        System.out.println("Repository");
    }
}

//组件
@Component
public class UserComponent {
    public void doComponent(){
        System.out.println("Component");
    }
}

//配置
@Configuration
public class UserConfiguration {
    public void doConfiguration(){
        System.out.println("userConfiguration");
    }
}

//启动类
public class App {
    public static void main(String[] args) {
        //获取spring上下文
        ApplicationContext context=new ClassPathXmlApplicationContext("Spring-config.xml");

        //获取Controller bean对象
        //使用注解默认是小驼峰
        UserController userController=context.getBean("userController",UserController.class);

        userController.SayHello();
        
        //获取Service bean对象
        UserService userService=context.getBean("userService",UserService.class);

        userService.doService();

        //获取Repository bean对象
        UserRepository userRepository=context.getBean("userRepository",UserRepository.class);

        userRepository.DoRepository();

        //获取Component bean对象
        UserComponent userComponent=context.getBean("userComponent",UserComponent.class);

        userComponent.doComponent();

        //获取Configuration bean对象
        UserConfiguration userConfiguration=context.getBean("userConfiguration",UserConfiguration.class);

        userConfiguration.doConfiguration();
    }
}

总结:Controller(控制器)、Service(服务)、Repository(仓库)、Configuration(配置)都是基于Component 他们的作用都是将Bean存储到Spring中

获取bean时,都需要将类的首字母小写

命名规则

默认情况下,使用5大类注解获取bean名称,要将首字母小写

特例:当首字母和第二个字母都是大写的时候,那么获取bean名称时,使用原名称即可

创建类时,如果要把类放入spring内管理,那么你的类名一定要遵守命名规则

1.首字母大写,后续小写

2.首字母大写,第二个字母也是大写

为什么要这样命名呢?

查看源码

ctrl+鼠标左键进入

    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);
    }

可以看到源码是这么写的

如果为空时,返回源字符串

如果长度大于1 并且 字符串第二个字符串和首字符都是大写的时候,也返回源字符串

只有当这两个条件不成立的时候,就把字符串第一个数改为小写

测试

        //这个获取bean对象时,需要首字母小写
	   String userComponent = "UserComponent";
	   //这个首字母和第二个字母都是大写,获取bean对象时,使用源类名即可
        String sComponent = "SComponent";
        System.out.println(Introspector.decapitalize("UserComponent"));
        System.out.println(Introspector.decapitalize("SComponent"));

存储bean对象

创建一个普通类,创建一个输入数据类

这样就把User放入spring内管理,并且初始化,初始化的方法必须加Bean

为什么bean必须和五大类的其中一个配合用才可以呢?

性能原因,spring不可能把全部的类全加入到spring内管理,那太消耗性能了,所以必须先表名五大类其中一个,加了类注解,再类注解下加了bean 方法注解,才会把该类加入到spring内管理

Bean

Spring内管理的对象统称为Bean

方法的命名规则就是方法名

当多个类使用同一个方法名,并且对象都存入spring中时,可以给方法名起别名

起别名的方法有三种

 @Bean(name="UserBean")

    //取多个名称
    @Bean(name={"studentbean","stubean"})
    @Bean("StudentBean")
    //重命名方法名  获取bean对象时就之间写重命名的即可
    //当重命名后,原来的方法名就不能使用了

DI注入

DI注入时机取决于bean的作用域,比如默认情况bean的作用域为单例模式,当需要对象时,才会注入。

DI注入都是从Spring内获取,Spring内没有的就没法注入

对象注入有三种

  1. 属性注入 (Field Injection)
  2. Setter注入 (Setter Injection)
  3. 构造方法注入 (Constructor Injection)

@Autowired

属性注入(Field Injection)

@Autowired //添加注解
    private UserService userService;//获取userService对象


    public void SayHello(){
        userService.doService();//使用userService方法
        System.out.println("Hello");
    }

启动类内不能注入,因为static执行速度是非常快的,在属性还没注入时,main函数已经执行了。所以main执行时,获取不到从spring获取的对象。

优点

现简单,使用方便,注入之后即可使用

缺点

1.不能注入被final修饰的对象

原因:final关键字在Java中表示一个字段是不可变的,它必须在声明时或在构造函数中被初始化,并且之后不能被修改。

当你使用依赖注入时,注入的值通常是在运行时由容器设置的,这意味着属性的值是在对象创建之后才确定的。但是,由于final字段必须在构造函数中被初始化,这就产生了一个矛盾:你不能在构造函数中给final字段赋值,因为那时注入的值还没有确定。

除非直接赋值或在构造方法内赋值

2.通用性问题 只适用于IoC框架(容器)
3.更容易违背单一设计原则

单一职责原则指出,一个类应该只有一个引起变化的原因,即一个类应该只负责一项任务。当使用 @Autowired 进行属性注入时,可能会导致以下问题:

  1. 职责不清晰:如果一个类中有多个 @Autowired 注解的属性,那么这个类可能承担了多个职责。这违反了单一职责原则,因为如果这些依赖中的任何一个发生变化,这个类可能需要修改。
  2. 依赖过多:一个类如果依赖了太多的其他类,那么它就变得复杂,难以理解和维护。这可能导致类之间的耦合度增加,违反了高内聚低耦合的设计原则。

Setter注入(Setter Injection)

//setter注入 (setter Injection)
    private UserService userService;

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

优点

符合单一设计原则 (一个setter只针对一个对象)

缺点

1.不能注入一个不可变(final)的对象 (和属性注入一样)

原因:final关键字在Java中表示一个字段是不可变的,它必须在声明时或在构造函数中被初始化,并且之后不能被修改。

当你使用依赖注入时,注入的值通常是在运行时由容器设置的,这意味着属性的值是在对象创建之后才确定的。但是,由于final字段必须在构造函数中被初始化,这就产生了一个矛盾:你不能在构造函数中给final字段赋值,因为那时注入的值还没有确定。

2.注入对象可能会被改变 (致命问题) set方法可能会被调用多次 被调用就有被修改的风险

构造方法注入(Constructor Injection)

官方推荐做法

//构造方法注入(Constructor Injection)
    private UserService userService;

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

当当前类只有一个构造方法,那@Autowired可以省略

一个构造方法内可以注入多个对象

//构造方法注入(Constructor Injection)
    private UserService userService;
    private UserRepository userRepository;

    @Autowired
    public UserController(UserService userService,UserRepository userRepository){
        this.userService=userService;
        this.userRepository=userRepository;
    }

一个类可以有多个构造方法,但是只允许一个构造方法有@Autowired注解(DI注入构造只允许有一个)

并且,构造方法的参数只允许有在spring内存储的,其他参数没有办法传入构造方法,所以会报错。

优点

1.可以注入final修饰的对象

final修饰的变量必须赋初始值

赋值只有两种方法

1.创建时直接赋值

2.在构造方法中赋值

构造注入刚好满足第二种需求,所以构造注入允许注入final的对象

2.注入对象不会被修改

构造方法只能执行一次,所以赋值完就不会再赋值

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

使用前一定会被构造方法初始化

4.通用性更好,当不使用IoC容器时,构造方法依旧奏效

@Resource

也是实现对象注入

注入方式也是同样的属性注入、setter注入

但Resource不支持构造注入

方式也是一样的,只是注解不同

属性注入

//    属性注入
//读取spring中名为userService的对象,赋值给当前注入的对象
//有了这个name  所以即使下面的名称不一致,依靠上面的name依旧可以找到指定对象
    @Resource(name="userService")
    private UserService userService;

Resource可以指定注入对象的名称

Setter注入

    //setter注入
    private UserController userController;

    @Resource
    public void setUserController(UserController userController) {
        this.userController = userController;
    }

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第十二届蓝桥杯省赛真题 Java C 组【原卷】

文章目录 发现宝藏【考生须知】试题 A: ASC试题 B: 空间试题 C: 卡片试题 D: 相乘试题 E: 路径试题 F: 时间显示试题 G: 最少砝码试题 H : \mathrm{H}: H: 杨辉三角形试题 I: 左孩子右兄弟试题 J : \mathrm{J}: J: 双向排序 发现宝藏 前些天发现了一个巨牛的人工智能学习网站…

Spring如何控制Bean的加载顺序

前言 正常情况下,Spring 容器加载 Bean 的顺序是不确定的,那么我们如果需要按顺序加载 Bean 时应如何操作?本文将详细讲述我们如何才能控制 Bean 的加载顺序。 场景 我创建了 4 个 Class 文件,分别命名为 FirstInitialization Se…

国家软考办:2024年上半年软考考试安排

按照《2024年计算机技术与软件专业技术资格(水平)考试工作安排及有关事项的通知》(计考办〔2024〕1号)文件精神,结合各地机位实际,现将2024年上半年计算机软件资格考试有关安排通告如下: 一、考…

代码随想录算法训练营第36期DAY19

DAY19 104二叉树的最大深度 根节点的高度就是最大深度。 非递归法: /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode() : val(0), left(nullptr), right(nullptr) …

Maven的使用

1.第一个Maven工程 1.1 创建约定目录结构 ​ Hello ​ src ​ ——main(存放主程序) ​ ————java(存放源代码文件) ​ ————resources(存放配置文件和资源文件) ​ ——test(存放测试程序) ​ ————java ​ ————resources ​ pom.xml 1.2 创建核心文件 pom.xml …

知识竞赛奖品买什么好,不是贵的就好

知识竞赛奖品分精神奖品和物质奖品两种,两种缺一不同,精神奖品主要是荣誉证书和奖牌或奖杯之类,满足选手精神需要,另外,物质奖品也不可以少,否则选手没有参与积极性,物质奖品可以是奖金或奖品&a…

如何确保UDP文件传输工具有最低稳定的传输速度?

在当前日新月异的数字时代背景下,文件传输工具已经成为我们日常生活与工作中不可或缺的一部分,尤其针对那些频繁涉及即时数据交互与多媒体流通的场景。 UDP协议,以其突出的高速传输与低延迟特性,脱颖而出成为众多用户的首选。不过…

Whistle 在手机上配置代理

1、运行Whistle w2 start 在浏览器打开 http://127.0.0.1:8899/#rules 2、点击https展示whistle下载二维码,用手机浏览器扫码下载并安装rootCA.crt 证书 安装时选择【用于VPN和应用】 3、与电脑连接同一网络WiFi,右键修改网络, 显示高级选…

nmap使用教程

nmap使用教程 一、nmap简介二、nmap常用命令2.1、target specification(目标规范)2.1.1、用法2.1.2、详情 2.2、HOST DISCOVERY(主机发现)2.2.1、用法2.2.2、详情 2.3、SCAN TECHNIQUES(扫描技术)2.4、PORT…

与Apollo共创生态:Apollo7周年大会的心得体会

目录 一、开放创新 - Apollo自动驾驶开放平台二、合作共赢 - 企业解决方案Apollo X三、共创生态 - Apollo开放平台企业生态计划四、结语 - 个人的一些感悟 自2017年诞生以来,Apollo开放平台在不懈的迭代与创新中,历经了基础能力夯实、场景能力拓展和系统…

【复试分数线】C9历年分数线汇总(第二弹)

今天我将分析C9中主要考信号的5所院校:复旦大学、上海交通大学、南京大学、哈尔滨工业大学、西安交通大学。 这次会为大家整理四电四邮的整理了近三年各院校的复试分数线作为参考,大家可以参考! 大多数院校采取的是1.2:1差额的形式复试。举…

Web自动化测试 selenium 定位元素方法有哪些?

简介: 在Selenium Web自动化测试中,元素定位是非常重要的一步。它的目的是通过一些特定的属性或者位置信息来定位页面上的元素,以便进行后续的操作。本文将从0到1,详细介绍Selenium Web自动化测试中的元素定位方法。 文章正文&am…

查看微信小程序主包大小

前言 略 查看微信小程序主包大小 在微信开发者工具右上角找到“详情->基本信息” 查看微信小程序主包构成 通过微信开发者工具中的“代码依赖分析”工具查看

whisper使用

whisper使用 1. 直接调用 语音识别2. 语种识别 whisper.detect_language()和whisper.decode()3. 指定要识别的语种做语音识别**whisper 源码的transcribe函数** 函数解析1. transcript.py2. tokenizer.py3. audio.py4. __ init__.py github: https://gitcode.com/openai/whispe…

原来pip是有默认路径的。

今天一直报错: bash: /root/data1/anaconda3/envs/li_3_10/bin/pip: /root/lsc/anaconda3/envs/li_3_10/bin/python: bad interpreter: No such file or directory 原来是root/data1/anaconda3/envs/li_3_10/bin/pip: 这个位置的pip 自身带默认路径,然…

Certbot免费证书的安装,使用,自动续期

首先你得先确认你得linux是那个操作系统,可以用这几个命令试一下。两个都可以试试 cat /etc/os-releaseuname -a然后看是Certbot得安装: CentOS: yum update yum install certbot -y Debian: apt update apt install certbot -y 有的云…

【文化课学习笔记】【物理】功与能

【物理】功与能 功 基础概念 定义 一个物体在力的作用下,沿力的方向,通过一段距离(位移),则称这个力做了功。 公式 功的定义式: \[W Fx \] 这里的 \(x\) 指的是物体沿力的方向上发生的位移。由于力 \(F\) 和位移 \(x\) 都是矢量&…

【回溯算法】【Python实现】符号三角形问题

文章目录 [toc]问题描述回溯法时间复杂性Python实现 问题描述 下图是由 14 14 14个“ ”和 14 14 14个“ − - −”组成的符号三角形, 2 2 2个同号下面都是” “, 2 2 2个异号下面都是“ − - −” 在一般情况下,符号三角形的第一行有 n…

前端 怎么让聊天列表在第一次渲染的时候自动定位到最新位置

常见的定位到聊天最新位置一般是&#xff0c;正常渲染之后&#xff0c;使用scrollIntoView或者scrollTo去处理。 今天分享另外一种方法 <!DOCTYPE html> <html lang"en"><head><meta charset"utf-8" /><title>Demo</ti…