基于注解配置bean

文章目录

    • 1.基本使用
        • 1.基本介绍
        • 2.快速入门
          • 1.引入jar包
          • 2.MyComponent.java
          • 3.UserAction.java
          • 3.UserDao.java
          • 4.UserService.java
          • 5.beans05.xml
          • 6.断点查看bean对象是否创建
          • 7.测试
        • 3.注意事项和细节
    • 2.自己实现spring注解
        • 1.需求分析
        • 2.思路分析图
        • 3.编写自定义注解ComponentScan
        • 4.编写配置类SunSpringConfig
        • 5.编写容器SunSpringApplicationContext
        • 6.测试
    • 3.自动装配
        • 1.AutoWired方式
          • 1.基本说明
          • 2.UserDao.java
          • 3.UserService.java
          • 4.测试
        • 2.Resource方式(推荐)
          • 1.基本说明
          • 2.UserDao.java
          • 3.UserService.java
    • 4.泛型依赖注入
        • 1.基本说明
          • 1.基本介绍
          • 2.参考关系图

1.基本使用

1.基本介绍

image-20240219101916177

2.快速入门
1.引入jar包

image-20240219102154951

2.MyComponent.java
package com.sxs.spring.component;import org.springframework.stereotype.Component;/*** @Component 标识该类是一个组件,当不确定该类的层级的时候就使用这个注解* @author 孙显圣* @version 1.0*/@Component
public class MyComponent {
}
3.UserAction.java
package com.sxs.spring.component;import org.springframework.stereotype.Controller;/*** @Controller 用于标识该类是一个控制器(相当于servlet)* @author 孙显圣* @version 1.0*/
@Controller
public class UserAction {
}
3.UserDao.java
package com.sxs.spring.component;import org.springframework.stereotype.Repository;/*** @Repository 用来标识该类是一个dao* @author 孙显圣* @version 1.0*/
@Repository
public class UserDao {
}
4.UserService.java
package com.sxs.spring.component;import org.springframework.stereotype.Service;/*** @Service 用于标识该类是一个Service* @author 孙显圣* @version 1.0*/
@Service
public class UserService {
}
5.beans05.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: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 https://www.springframework.org/schema/context/spring-context.xsd"><!--component-scan 表示对指定包下的类进行扫描,并创建对象到容器base-package 指定要扫描的包--><context:component-scan base-package="com.sxs.spring.component"></context:component-scan>
</beans>
6.断点查看bean对象是否创建

image-20240219104840942

7.测试
    //通过注解来配置bean@Testpublic void setBeanByAnnotation() {//从类路径下读取配置文件ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");//分别获取这四个对象,由于是单例的所以可以直接通过类型获取MyComponent component = ioc.getBean(MyComponent.class);UserAction action = ioc.getBean(UserAction.class);UserDao userDao = ioc.getBean(UserDao.class);UserService userService = ioc.getBean(UserService.class);System.out.println("" + component + action + userDao + userService);}

image-20240219105551384

3.注意事项和细节

image-20240219105946438

image-20240219133850259

image-20240219133918902

image-20240219134100805

image-20240219134942963

2.自己实现spring注解

1.需求分析

image-20240219135303466

image-20240219135325093

2.思路分析图

image-20240219140946226

3.编写自定义注解ComponentScan
package com.sxs.spring.annotation;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** 自定义注解:用于指定要扫描的包** @author 孙显圣* @version 1.0*/
@Target(ElementType.TYPE) //指定目前的注解可以修饰TYPE程序元素
@Retention(RetentionPolicy.RUNTIME) //指定注解的保留范围,在运行时可以生效
public @interface ComponentScan {String value() default ""; //指定注解可以传入一个String类型的值,用于指定要扫描的包
}
4.编写配置类SunSpringConfig
package com.sxs.spring.annotation;/*** @author 孙显圣* @version 1.0*/
@ComponentScan(value = "com.sxs.spring.component") //自定义注解:指定要扫描的包
public class SunSpringConfig {}
5.编写容器SunSpringApplicationContext
package com.sxs.spring.annotation;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;import java.io.File;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;/*** 类似于Spring原生的ioc容器** @author 孙显圣* @version 1.0*/
public class SunSpringApplicationContext {//传进来一个配置类的Class对象private Class configClass;//存放对象的容器private final ConcurrentHashMap<String, Object> ioc = new ConcurrentHashMap<>();//构造器,接收配置类的class对象public SunSpringApplicationContext(Class configClass) throws ClassNotFoundException, InstantiationException, IllegalAccessException {this.configClass = configClass;//获取要扫描的包//1.首先反射获取类的注解信息ComponentScan componentScan = (ComponentScan) this.configClass.getDeclaredAnnotation(ComponentScan.class);//2.通过注解来获取要扫描的包的路径String path = componentScan.value();//得到要扫描包的.class文件//1.获取类加载器ClassLoader classLoader = SunSpringApplicationContext.class.getClassLoader();//2.获取要扫描包的真实路径,默认刚开始在根目录下path = path.replace(".", "/");URL resource = classLoader.getResource(path);//3.由该路径创建一个文件对象,可使用resource.getFile()将URL类型转化为String类型File file = new File(resource.getFile());//4.遍历该文件夹下的所有.class文件if (file.isDirectory()) {File[] files = file.listFiles();for (File f : files ) {//反射注入容器//1.获取所有文件的全路径String absolutePath = f.getAbsolutePath();//只处理class文件if (absolutePath.endsWith(".class")) {//2.分割出类名String className = absolutePath.substring(absolutePath.lastIndexOf("\\") + 1, absolutePath.indexOf("."));//3.得到全路径String fullPath = path.replace("/", ".") + "." + className;//4.类加载器获取Class对象(也可以通过Class.forName,区别是后者会使类被静态初始化),判断是否有那四个注解Class<?> aClass = classLoader.loadClass(fullPath);if (aClass.isAnnotationPresent(Component.class) || aClass.isAnnotationPresent(Controller.class)|| aClass.isAnnotationPresent(Service.class) || aClass.isAnnotationPresent(Repository.class)) {//5.反射对象并放入到容器中Class<?> clazz = Class.forName(fullPath);Object o = clazz.newInstance();//默认是类名首字母小写作为keyioc.put(StringUtils.uncapitalize(className), o);}}}System.out.println("ok");}}//返回容器中的对象public Object getBean(String name) {return ioc.get(name);}}
6.测试
package com.sxs.spring.annotation;import org.junit.jupiter.api.Test;/*** @author 孙显圣* @version 1.0*/
public class test {@Testpublic void SunSpringApplicationContextTest() throws ClassNotFoundException, InstantiationException, IllegalAccessException {SunSpringApplicationContext ioc = new SunSpringApplicationContext(SunSpringConfig.class);Object myComponent = ioc.getBean("myComponent");Object userAction = ioc.getBean("userAction");Object userDao = ioc.getBean("userDao");Object userService = ioc.getBean("userService");System.out.println("" + myComponent + userService + userAction + userDao);}
}

image-20240219160545576

3.自动装配

1.AutoWired方式
1.基本说明

image-20240219172851649

2.UserDao.java
package com.sxs.spring.component;import org.springframework.stereotype.Repository;/*** @Repository 用来标识该类是一个dao* @author 孙显圣* @version 1.0*/
@Repository
public class UserDao {public void sayHi() {System.out.println("hi");}
}
3.UserService.java
package com.sxs.spring.component;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;/*** @Service 用于标识该类是一个Service* @author 孙显圣* @version 1.0*/
@Service
public class UserService {//自动装配//1.通过UserDao这个类型来匹配,如果有多个实例,则使用第二种方式匹配//2.通过userDao这个属性名字作为id匹配实例,如果还是匹配不到则报错@AutowiredUserDao userDao;public void sayHi() {userDao.sayHi();}
}
4.测试
    //测试@autowire自动装配@Testpublic void autowireTest() {//获取容器ApplicationContext ioc = new ClassPathXmlApplicationContext("beans05.xml");UserService bean = ioc.getBean("userService", UserService.class);bean.sayHi();}

image-20240219173043506

2.Resource方式(推荐)
1.基本说明

image-20240219173244707

2.UserDao.java
package com.sxs.spring.component;import org.springframework.stereotype.Repository;/*** @Repository 用来标识该类是一个dao* @author 孙显圣* @version 1.0*/
@Repository
public class UserDao {public void sayHi() {System.out.println("hi");}
}
3.UserService.java
package com.sxs.spring.component;import org.springframework.stereotype.Service;import javax.annotation.Resource;/*** @Service 用于标识该类是一个Service* @author 孙显圣* @version 1.0*/
@Service
public class UserService {//自动装配//1.通过name匹配:直接根据注解的属性name来进行匹配,如果匹配不到直接报错//2.通过类型匹配:必须保证是单例的,如果有多个实例,则直接报错//3.默认:先通过name属性匹配,如果匹配不上则按照类型匹配,都匹配不上才会报错@ResourceUserDao userDao;public void sayHi() {userDao.sayHi();}
}

4.泛型依赖注入

1.基本说明
1.基本介绍

image-20240219184142629

2.参考关系图

image-20240219185501222

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

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

相关文章

【AI面试】工作和面试过程中,经常遇到的其他问题汇总(持续更新)

在与面试官在面对面进行交流的过程中,面试官不仅仅会针对简历中记录的内容进行深入的了解,还会进行一些发散性的提问。 目前也就很明显,就是要看看对方: 对于常见的问题是如何思考的?有没有在持续性的学习本领域的新知识?对于不知道的问题,是如何思考的?迁移能力咋样。…

Mybaties入门

文章目录 介绍持久层框架Jdbc缺点Mybaties简化整体框架ORM方式 Mybaties快速入门(Mapper代理)核心配置文件映射文件配置编写会话工具类 介绍 Mybaties是一款优秀的持久层框架&#xff0c;用于简化JDBC开发 持久层 负责将数据保存到数据库的那一层代码JavaEE三层架构&#x…

【双曲几何】圆盘上的三角形概念

目录 一、说明二、对偶三角形概念2.1 反演关系2.2 对偶关系2.3 找出三角形的对偶三角形 三、正交三角形概念3.1 通过对偶三角形&#xff0c;找到垂心3.2 正交三角形的概念3.3 中心射影点的概念 四、后记 一、说明 本文对双曲空间的三角形进行分析&#xff0c;本篇首先给出&am…

数据结构(data structure)(2)链表的运用

桶排序 e*len/(max1) e为每个元素&#xff0c;根据上式判断该元素放入哪个桶 桶排序适用于分布均匀的数组1.arr->length,max 2.Node[]-new Node[length] 3.扫描->hash->下标->元素入桶 4.出桶<>排序排序的输出private void sort(int[] arr){int lengtharr.le…

漆包线行业你了解多少?专业漆包线行业MES生产管理系统

今天就说说漆包线行业&#xff0c;漆包线是工业电机&#xff08;包括电动机和发电机&#xff09;、变压器、电工仪表、电力及电子元器件、电动工具、家用电器、汽车电器等用来绕制电磁线圈的主要材料。 漆包线上游是铜杆行业&#xff0c;下游是各种消费终端&#xff0c;主要是电…

Java基础知识总结(66)

** FileOutputStream练习 */ public class FileOutputStreamDemo { public static void main(String[] args) { String path "D:\\IoDemo\\test2.txt"; //如果文件不存在&#xff0c;则自动创建 //append:是指是否在原有内容后追加&#xff0c;默认为FALSE try(Outp…

Python代码实战——深入解析缓存问题:穿透、击穿、雪崩

作为Python开发者处理缓存相关问题,可以通过具体的场景和代码示例来更好地理解和解决缓存穿透、缓存击穿和缓存雪崩。 缓存穿透 场景:用户频繁请求数据库中不存在的数据,导致每次请求都绕过缓存直接查询数据库,增加数据库的压力。 解决方案: 设置空值缓存:当查询数据不…

代码优化实践之税率计算问题

开篇 今天的问题来自于《编程珠玑》第三章【数据决定程序结构】&#xff0c;这里提出了几条代码优化相关的原则&#xff0c;受益不浅。下面是提到的几条原则&#xff1a; 使用数组重新编写重复代码。冗长的相似代码往往可以使用最简单的数据结构——数组来更好的表述&#xff1…

C++入门之类和对象(中)

C入门之类和对象(中) 文章目录 C入门之类和对象(中)1. 类的6个默认对象2. 构造函数2.1 概念2.2 特性2.3 补丁 3. 析构函数3.1 概念3.2 特性3.3 总结 4. 拷贝构造函数4.1 概念4.2 特性4.3 总结 1. 类的6个默认对象 如果一个类中什么都没有&#xff0c;那么这个类就是一个空类。…

什么是代理IP?如何正确使用代理IP?

代理IP&#xff08;Proxy IP&#xff09;是一种网络技术&#xff0c;它允许用户通过一个中介服务器&#xff08;即代理服务器&#xff09;来访问互联网。具体来说&#xff0c;代理IP隐藏了用户的真实IP地址&#xff0c;使用第三方的IP地址进行网络访问。当用户发起网络请求时&a…

CAD小软件diy-读柴油机壳体装配图

读取一个柴油机壳体dxf图纸&#xff0c;一般这种装配体轮廓曲线都是用直线和圆弧拟合的&#xff0c;全部都是显示的白色实现&#xff0c;发现有线段间隙&#xff0c;拖动线段补上间隙。 这个测试放在蓝奏云上面 https://wwf.lanzout.com/ip1Xx1vvhbkh

tcp bbr pacing 的对与错

前面提到 pacing 替代 burst 是大势所趋&#xff0c;核心原因就是摩尔定律逐渐失效&#xff0c;主机带宽追平交换带宽&#xff0c;交换机不再能轻易吸收掉主机突发&#xff0c;且随着视频类流量激增&#xff0c;又不能以大 buffer 做带宽后备。因此&#xff0c;主机必须 pacing…

A-1:树状数组

A-1:树状数组 1.介绍Q1:树状数组解决什么问题&#xff1f;Q2:树状数组的使用1.前置知识&#xff1a;lowbit(x)2.单点修改3.求[1,n]的和4.区间查询5.hh Q3:树状数组是否优化了Q4:上图上例子解释上面说的东西(Important) 2.习题练习 1.介绍 树状数组是一个比较难以理解的高级数据…

什么存算分离?

存算分离&#xff08;Storage-Compute Separation 或 Storage-Compute Decoupling&#xff09;是一种数据架构设计理念&#xff0c;旨在将数据存储&#xff08;Storage&#xff09;和数据处理/计算&#xff08;Compute&#xff09;功能分离开来。这种设计允许存储资源和计算资源…

python笔记之高级特性

目录 一、is 与 二、深浅拷贝 三、生成器&#xff08;generator&#xff09; 1、列表推导式 2、列表生成器 3、函数生成器 四、迭代器 可迭代对象 五、闭包&#xff08;closure&#xff09; 六、装饰器 一、is 与 比较运算符。是用来比较两个值的大小的。&#xf…

C语言---单链表(二)

文章目录 前言1.准备工作2,打印链表、创建新的节点、销毁链表2.1.打印链表2.2.创建节点2.3.销毁链表 3.尾插、头插、尾删、头删3.1.尾插3.2.头插3.3.尾删3.4.头删 4.在特殊位置之前、之后插入、删除以及查找节点4.1.查找节点4.2.在指定位置之前插入4.3.在指定位置之后插入数组4…

赋值运算符

介绍 赋值运算符就是将某个运算后的值&#xff0c; 赋给指定的变量。 赋值运算符的分类 基本赋值运算符 例如&#xff1a; int a 10; 复合赋值运算符 &#xff0c; - &#xff0c; * &#xff0c; / &#xff0c; % 等 a b; [等价 a a b; ] a - b; [等价 a a - b; ] …

亚信安全入选中国数据安全市场图谱

近日&#xff0c;全球领先的IT市场研究和咨询公司IDC发布了《IDC Market Glance&#xff1a;中国数据安全市场图谱&#xff0c;2024》报告&#xff08;以下简称“报告”&#xff09;&#xff0c;报告展示了中国数据安全市场的构成和格局&#xff0c;遴选出不同细分市场领域的主…

C语言中的结构体:从定义到传递

前言 结构体是C语言中一种重要的数据类型&#xff0c;它允许我们将不同类型的数据组合成一个整体&#xff0c;并以自定义的方式进行操作。通过结构体&#xff0c;我们可以更加灵活地管理和处理复杂的数据结构&#xff0c;从而提高程序的可读性和可维护性。本篇博客将从结构体的…

jetcache fastjson 泛型复杂对象JSON序列 ,反序列化

Jetcache fastjson 泛型复杂对象JSON序列 ,反序列化 默认的FastJson2 序列化存在问题增强FastJson 支持Encode 编码器Decode 解码器 默认的FastJson2 序列化存在问题 默认的序列化不能转换List 中的泛型数据类型, 从缓存拿取的list集合对象数据全部都转换成了JSONObject 增强F…