Spring注解详解(使用注解的方式完成IOC)

news2024/11/19 17:41:32

补充:xml配置

最开始(Spring 1.x),Spring都是通过xml配置控制层(controller)--业务逻辑层(service)--dao层--数据源的关系,但是比较复杂

Spring 2.x的时候,随着JDK1.5支持注解的方式,实现了 "xml + 注解" 的开发模式,大大减少了xml配置,同时也简化了项目的开发

...

而目前springboot是全注解的方式

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:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
 
    <!--可以配置多个数据源,用哪个就引用哪个-->
    <!--mysql-->
    <bean id="ds" class="com.qzcsbj.dao.impl.DataSource">
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="url" value="jdbc:mysql://192.168.168.168:3360/gifts?useUnicode=true&characterEncoding=utf-8&useSSL=true"/>
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
    </bean>
 
    <!--dao引用ds-->
    <bean id="dao" class="com.qzcsbj.dao.impl.UserDaoImpl">
        <property name="ds" ref="ds"/>
    </bean>
 
    <!--service引用dao-->
    <bean id="service" class="com.qzcsbj.service.impl.UserServiceImpl">
        <property name="userDao" ref="dao"/>
    </bean>
 
    <!--controller引用service-->
    <bean id="controller" class="com.qzcsbj.controller.UserController">
        <property name="userService" ref="service"/>
    </bean>
</beans>

注解使用

引入Context的约束

输入下面后

会自动添加context的约束

<?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:context="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 http://www.springframework.org/schema/context/spring-context.xsd">

配置注解

指定扫描包下所有类中的注解

<?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:context="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 http://www.springframework.org/schema/context/spring-context.xsd">

    <!--扫描注解类-->
    <context:component-scan base-package="com.qzcsbj.*"/>

</beans>

Component

@Component:给类创建对象,默认的对象名称是类名首字母小写

测试:对象名是student

package com.qzcsbj.test;

import com.qzcsbj.bean.Student;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
public class Test2 {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student stu = context.getBean("student", Student.class);
        System.out.println(stu);
    }
}

结果:没有值(下图展示的是类型默认值),是因为没有注入值

也可以给对象取别的名字,后续就只能用这个自定义的对象名

@Component("stu")
public class Student {
    private String name;
    private int age;

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

测试:对象名是stu

Student stu = context.getBean("stu", Student.class);

Value

给属性赋值:@Value("属性值") 等同于 @Value(value="属性值")

@Component("stu")
public class Student {
    @Value("jack")
    private String name;

    @Value("18")
    private int age;

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

测试

Autowired

@Autowired:自动装配对象属性(根据类型自动装配一个) 

接口

package com.qzcsbj;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
public interface Alimal {
    void eat();
}

Cat实现类

package com.qzcsbj;

import org.springframework.stereotype.Component;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
@Component
public class Cat implements Alimal {
    public void eat() {
        System.out.println("==============cat eat fish");
    }
}

Dog实现类

package com.qzcsbj;

import org.springframework.stereotype.Component;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
@Component
public class Dog implements Alimal {
    public void eat() {
        System.out.println("==========dog eat bone");
    }
}

给对象属性注入值,报错

因为匹配到多个

注释一个就不会报上面的错了

给Student的对象属性加上get方法

    public Alimal getAlimal() {
        return alimal;
    }

测试

package com.qzcsbj.test;

import com.qzcsbj.bean.Student;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
public class Test2 {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student stu = context.getBean("stu", Student.class);
        stu.getAlimal().eat();
    }
}

结果

Qualifier

@Qualifier:如果匹配到多个对象,可以用Qualifier来指定要匹配哪一个对象,需要配合@Autowired使用

给Cat类加上注解:@Component

下面这种方式写,就不报错了

测试结果

Resource

@Resource:默认是根据类型自动装配一个,如果匹配多个会异常,也可以指定名字匹配,@Resource(name="obj") == @Autowired + @Qualifier("obj")

    // @Autowired
    // @Qualifier("cat")
    @Resource(name = "cat")
    private Alimal alimal;

Scope

@Scope:用于指定对象作用域,在类上添加此注解

单例:singleton

多例:prototype 

@Scope(scopeName = "singleton"),或者:@Scope("singleton")
@Scope(scopeName = "prototype"),或者:@Scope("prototype")

实体类 

package com.qzcsbj.bean;

import com.qzcsbj.test.Alimal;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
@Component("stu")
public class Student {
    @Value("jack")
    private String name;

    @Value("18")
    private int age;

    // @Autowired
    // @Qualifier("cat")
    @Resource(name = "cat")
    private Alimal alimal;

    public Alimal getAlimal() {
        return alimal;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", alimal=" + alimal +
                '}';
    }
}

测试

package com.qzcsbj.test;

import com.qzcsbj.bean.Student;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @公众号 : 全栈测试笔记
 * @博客 : www.cnblogs.com/uncleyong
 * @微信 : ren168632201
 * @描述 : <>
 */
public class Test2 {
    @Test
    public void test(){
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Student stu = context.getBean("stu", Student.class);
        Student stu2 = context.getBean("stu", Student.class);
        System.out.println(stu==stu2);
    }
}

测试结果是true,因为默认是单例 

默认单例:@Scope("singleton")

改为多例:@Scope("prototype")

测试结果

其它注解

@Service:用于标注业务层,给业务逻辑层生成对象

@Controller:用于标注控制层,给控制层生成对象

@Repository:用于标注数据访问层,给dao层生成对象,说明:Mybatis的dao层是自动生成对象的,所以不需要这个注解

说明:不是上面任何一层,就加@Component注解;其它,上面三层也可以用@Component注解,但是用对应层的注解能见名知意。

【bak】

原文会持续更新,原文地址:https://www.cnblogs.com/uncleyong/p/17020010.html

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

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

相关文章

Vue自定义指令,自定义插件,过滤器,混入,nextTick

自定义指令&#xff1a;自己定义类似指令的技术。V-开关的特殊属性&#xff0c;是一个对象&#xff0c;自己定义其作用。 指令: v-特殊属性 * vue内置指令: v-html v-text v-pre * v-bind v-on v-if v-show v-for …

我的前端学习经历

我最近在开发一个NFT相关的Saas&#xff0c;部分截图如下&#xff1a;这是我一段时间前&#xff0c;朋友圈发的图&#xff0c;现在Saas在页面上有点变化&#xff0c;但懒得再截图了。客观而言&#xff0c;布局还可以&#xff0c;这一套的技术栈是&#xff1a;React TailwindCs…

​无线数据终端DTU的电路防护元器件推荐产品型号

​无线数据终端DTU是专门用于将串行数据转换为IP数据或将IP数据转换为串行数据通过无线通信网络传输的无线终端设备&#xff0c;因此对于它来说ESD静电放电及雷击浪涌的防护显得尤其重要。 DTU已广泛应用于电力、环保、LED信息发布、物流、水文、气象等行业&#xff0c;其硬件…

【人工智能原理自学】方差代价函数:知错

&#x1f60a;你好&#xff0c;我是小航&#xff0c;一个正在变秃、变强的文艺倾年。 &#x1f514;笔记来自B站UP主Ele实验室的《小白也能听懂的人工智能原理》。 &#x1f514;本文讲解一元一次函数感知器&#xff1a;如何描述直觉&#xff0c;一起卷起来叭&#xff01; 目录…

[oeasy]python0037_字符画艺术_asciiview_自制小动物_imagick_asciiart

牛说(cowsay) 回忆上次内容 我们狂飙了一路 从用shell 直接执行 python程序到用shell 循环执行 python程序 循环体中 把 python的 输出结果 用管道 交给了 figlet 把 figlet的 输出结果 用管道 交给了 cowsay 把 cowsay的 输出结果 用管道 交给了 lolcat 最后 提权 直接运行 s…

课程设计 | 学生成绩管理系统

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

减小 Go 代码编译后的二进制体积

1 基线用例 减小编译后的二进制的体积&#xff0c;能够加快程序的发布和安装过程。接下来呢&#xff0c;我们分别从编译选项和第三方压缩工具两方面来介绍如何有效地减小 Go 语言编译后的体积。 我们采用同一个测试工程来测试不同方式的效果。 使用的测试工程如下&#xff0…

SQL全自动化检查神器

介绍 Yearning MYSQL 是一个SQL语句审核平台。提供查询审计&#xff0c;SQL审核等多种功能&#xff0c;支持Mysql&#xff0c;可以在一定程度上解决运维与开发之间的那一环&#xff0c;功能丰富&#xff0c;代码开源&#xff0c;安装部署容易&#xff01; 功能介绍 SQL查询查询…

Prometheus配合 alertmanager 使用邮箱报警

部署Prometheus 和 Alertmanager略 安装包部署prometheusGrafananode_exporter_争取不加班&#xff01;的博客-CSDN博客 prometheus监控报警部署Alertmanager_争取不加班&#xff01;的博客-CSDN博客 编辑Alertmanager配置文件 vim alertmanager/alertmanager.yml global: res…

MySQL高可用之主备同步:MySQL是如何保证主备一致的

&#x1f3c6;今日学习目标&#xff1a; &#x1f340;MySql是如何保证主备一致的 ✅创作者&#xff1a;林在闪闪发光 ⏰预计时间&#xff1a;30分钟 &#x1f389;个人主页&#xff1a;林在闪闪发光的个人主页 &#x1f341;林在闪闪发光的个人社区&#xff0c;欢迎你的加入:…

【Java编程进阶】封装继承多态详解

推荐学习专栏:Java 编程进阶之路【从入门到精通】 文章目录 1. 封装2. 继承2.1 继承的语法2.2 子类重写父类的方法2.3 子类隐藏父类的方法2.4 super 关键字2.5 final 关键字2.6 父类子类类型转换3. 多态4. 总结Java 是一门面向对象程序设计语言,其具有封装,继承和多态三大特…

面向对象的特征之三:多态性

文章目录一、理解多态性二、什么是多态性三、多态性的使用——虚拟方法调用四、多态性使用前提五、适用范围六、虚拟方法调用详细介绍多态性是编译期的还是运行期的&#xff1f;举例每日一考七、instanceof关键字的使用引入&#xff1a;关于多态性的讨论向下转型&#xff1a;in…

Linux-7 文本编辑vi/vim

Linux-7 文本编辑vi/vim vim介绍 什么是vim&#xff1f; vi和vim是Linux下的一个文本编辑工具。&#xff08;可以李姐为Windows的记事本或word文档&#xff09; 为什么要使用vim&#xff1f; 因为Linux系统一切皆为文件&#xff0c;而我们工作最多的就是修改某个服务的配置&a…

网络安全——投票系统缺陷(靶场实战)

我们需要利用漏洞来把投票信息刷到第一位 我们可以利用 HTTP_X_FORWARDED_FOR 来进行获取伪造 我们再次进行投票的时候&#xff0c;我们抓取数据包的格式 我们采用上述方法进行伪造 增加变量&#xff0c;我们采用多IP攻击 选中247点击send to Intruder 选中247和1点击 add&…

基于Xlinx的时序分析与约束(8)----关于时序路径、时钟悲观度和建立时间/保持时间的一些问题

写在前面 最近研究vivado里的时序分析路径时&#xff0c;发现了3个很有意思的问题。经过一番查找资料后&#xff0c;总算把问题搞明白了&#xff0c;在这里分享给大家。 1、为什么同一条时序路径在报表里的值不一样&#xff1f; 在如下文件建立的工程中&#xff1a; module te…

Window10下配置Maxim SDK

参考网址&#xff1a; 微信&#xff08;中文&#xff09;&#xff1a;【嵌入式AI开发&Maxim篇一】美信Maxim78000Evaluation Kit AI部署流程初探 GitHub&#xff1a;MaximAI_Documentation/MAX78000_Feather at master MaximIntegratedAI/MaximAI_Documentation 下载地址…

【回答问题】ChatGPT上线了!如何安装python-ipopt?python-ipopt有哪些用法?

如何安装python-ipopt&#xff1f; 要安装 python-ipopt&#xff0c;你需要先安装 Ipopt 库。这个库是用 C 编写的&#xff0c;所以你还需要安装一些 C 编译器。 在 Linux 系统上&#xff0c;你可以使用下面的命令来安装 Ipopt 和相关的依赖项&#xff1a; 复制 sudo apt-g…

excel成本统计:如何进行区域筛选,多条件求和?

最近有位小伙伴被一个计算产品成本的问题难住了&#xff0c;要求是根据配件成本核算出成品的成本。这个问题看上去似乎有点复杂&#xff0c;感觉一下子想不出好的解决办法&#xff0c;实际上&#xff0c;却非常简单&#xff0c;而且仅用常见的求和函数&#xff0c;就能轻松解决…

Mybatis源码分析(四)Mapper文件的解析

目录一 Mapper的使用二 MapperElement的解析三 解析cache-ref节点四 解析Cache节点五 解析ParameterMap节点六 解析ResultMap节点七 解析Sql节点八 处理各个数据库操作语句官网&#xff1a;mybatis – MyBatis 3 | 简介 参考书籍&#xff1a;《通用源码阅读指导书&#xff1a;M…

【每日一题】【LeetCode】【第一天】三数之和

三数之和的解决之路 题干表述 测试案列&#xff08;部分&#xff09; 第一次思路 这种其实是最暴力的&#xff0c;也是我脑海里第一个想到的最简单的方法了。 思路就是三个循环&#xff0c;一个循环去一个数&#xff0c;然后当三个下标不同&#xff0c;且对应的三个数相加为…