Spring底层机制环境搭建

文章目录

    • 1.模块创建和依赖引入
        • 1.聚合模块,下面有一个myspring
        • 2.查看父模块是否管理了子模块
        • 3.myspring模块引入基本包
    • 2.进行环境搭建
        • 1.目录概览
        • 2.UserController.java
        • 3.UserService.java
        • 4.UserDao.java
        • 5.AppMain.java
        • 6.beans.xml
        • 7.测试
        • 8.配置UserController.java为多例的,然后测试
        • 9.UserService调用add方法,然后测试
        • 10.引入Bean后置处理器
          • 1.位置
          • 2.MyBeanPostProcessor.java
          • 3.UserService.java 设置初始化方法
          • 4.beans.xml配置扫描
          • 5.测试
          • 6.注意事项
        • 11.引入AOP
          • 1.目录
          • 2.SmartAnimal.java
          • 3.SmartDog.java
          • 4.SmartAnimalAspect.java
          • 5.beans.xml开启aop注解并扫描aop包
          • 6.AppMain.java 测试AOP
          • 6.简单分析AOP和后置处理器的关系
    • 3.抛出问题
        • 1.bean是怎么注入容器的?
        • 2.为什么加了@Autowired就能被依赖注入?
        • 3.单例多例是怎么实现的?
        • 4.Bean的后置处理器是怎么实现的?
        • 5.原生Spring的AOP是如何实现的?
    • 4.将代码放到远程仓库
        • 1.VCS -》 share
        • 2.查看仓库

1.模块创建和依赖引入

1.聚合模块,下面有一个myspring

CleanShot 2024-08-04 at 13.50.33@2x

2.查看父模块是否管理了子模块

CleanShot 2024-08-04 at 13.51.05@2x

3.myspring模块引入基本包
<dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.8</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.3.8</version></dependency>
</dependencies>

2.进行环境搭建

1.目录概览

CleanShot 2024-08-04 at 14.06.39@2x

2.UserController.java
package com.sunxiansheng.myspring.component;import org.springframework.stereotype.Component;/*** Description: 就是一个Controller组件* @Author sun* @Create 2024/8/4 13:53* @Version 1.0*/
@Component
public class UserController {
}
3.UserService.java
package com.sunxiansheng.myspring.component;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;/*** Description: 一个Service组件* @Author sun* @Create 2024/8/4 13:54* @Version 1.0*/
@Component
public class UserService {/*** 依赖注入UserDao*/@Autowiredprivate UserDao userDao;public void add() {System.out.println("UserService 调用了UserDao的add方法");userDao.add();}}
4.UserDao.java
package com.sunxiansheng.myspring.component;import org.springframework.stereotype.Component;/*** Description: 一个Dao组件* @Author sun* @Create 2024/8/4 13:53* @Version 1.0*/
@Component
public class UserDao {public void add() {System.out.println("UserDao add...");}}
5.AppMain.java
package com.sunxiansheng.myspring;import com.sunxiansheng.myspring.component.UserController;
import com.sunxiansheng.myspring.component.UserDao;
import com.sunxiansheng.myspring.component.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;/*** Description: 启动类* @Author sun* @Create 2024/8/4 13:59* @Version 1.0*/
public class AppMain {public static void main(String[] args) {// 从类路径下加载beans.xml配置文件ApplicationContext ioc = new ClassPathXmlApplicationContext("beans.xml");// 从容器中获取UserController对象,这里获取两次,看是否是同一个对象UserController userController1 = (UserController) ioc.getBean("userController");UserController userController2 = (UserController) ioc.getBean("userController");System.out.println("userController1 == userController2 ? " + (userController1 == userController2));// 从容器中获取UserService对象UserService userService = (UserService) ioc.getBean("userService");System.out.println("userService = " + userService);// 从容器中获取UserDao对象UserDao userDao = (UserDao) ioc.getBean("userDao");System.out.println("userDao = " + userDao);}}
6.beans.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"><!-- 配置自动扫描的包 --><context:component-scan base-package="com.sunxiansheng.myspring.component"/></beans>
7.测试

CleanShot 2024-08-04 at 14.09.09@2x

8.配置UserController.java为多例的,然后测试

CleanShot 2024-08-04 at 14.11.14@2x

CleanShot 2024-08-04 at 14.11.24@2x

9.UserService调用add方法,然后测试

CleanShot 2024-08-04 at 14.13.20@2x

CleanShot 2024-08-04 at 14.13.29@2x

10.引入Bean后置处理器
1.位置

CleanShot 2024-08-04 at 14.38.08@2x

2.MyBeanPostProcessor.java
package com.sunxiansheng.myspring.process;import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;/*** Description: Bean的后置处理器* @Author sun* @Create 2024/8/4 14:19* @Version 1.0*/
@Component // 将这个类加入到容器中
public class MyBeanPostProcessor implements BeanPostProcessor {/*** 在每个Bean的初始化方法之前执行* @param bean* @param beanName* @return*/@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {// 这里可以提前对bean进行一些处理System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean.getClass());return bean;}/*** 在每个Bean的初始化方法之后执行* @param bean* @param beanName* @return*/@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean.getClass());return bean;}}
3.UserService.java 设置初始化方法

CleanShot 2024-08-04 at 14.38.34@2x

4.beans.xml配置扫描

CleanShot 2024-08-04 at 14.40.15@2x

5.测试

CleanShot 2024-08-04 at 14.40.32@2x

6.注意事项
  • bean的后置处理器在初始化方法调用前后执行
  • 触发时机为单例的第一次getBean和多例的每次getBean,也就是,每个Bean都会经过Bean的后置处理器处理
11.引入AOP
1.目录

CleanShot 2024-08-04 at 15.18.09@2x

2.SmartAnimal.java
package com.sunxiansheng.myspring.aop;/*** Description: SmartAnimal* @Author sun* @Create 2024/8/4 14:51* @Version 1.0*/
public interface SmartAnimal {public float getSum(float a, float b);public float getSub(float a, float b);}
3.SmartDog.java
package com.sunxiansheng.myspring.aop;import org.springframework.stereotype.Component;/*** Description: SmartDog* @Author sun* @Create 2024/8/4 14:51* @Version 1.0*/
@Component // 交给Spring容器管理
public class SmartDog implements SmartAnimal {@Overridepublic float getSum(float a, float b) {System.out.println("SmartDog...getSum...res=" + (a + b));return a + b;}@Overridepublic float getSub(float a, float b) {System.out.println("SmartDog...getSub...res=" + (a - b));return a - b;}
}
4.SmartAnimalAspect.java
package com.sunxiansheng.myspring.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** Description: 切面类* @Author sun* @Create 2024/8/4 14:53* @Version 1.0*/
@Component // 交给Spring容器管理
@Aspect // 标注这是一个切面类
public class SmartAnimalAspect {/*** @param joinPoint 保存了要切入的方法的信息* @Before 前置通知* execution(。。。) 切入表达式,表明要切入的方法,格式:格式:访问修饰符+返回类型 全类名 方法名(参数类型)*/@Before(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))")public void before(JoinPoint joinPoint) {// 获取方法签名Signature signature = joinPoint.getSignature();System.out.println("方法执行开始-日志-方法名-" + signature.getName()+ "-参数" + Arrays.asList(joinPoint.getArgs()));// 还可以获取目标对象,这样就可以反射进行任何操作了SmartDog target = (SmartDog) joinPoint.getTarget();System.out.println("目标对象-" + target.getClass());}/*** @param joinPoint 保存了要切入的方法的信息* @AfterReturning 返回通知*/@AfterReturning(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))")public void afterReturning(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法执行正常结束-日志-方法名-" + signature.getName());}/*** @param joinPoint* @AfterThrowing 异常通知*/@AfterThrowing(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))")public void throwing(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法出现异常-日志-方法名-" + signature.getName());}/*** @param joinPoint* @After 后置通知*/@After(value = "execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))")public void after(JoinPoint joinPoint) {Signature signature = joinPoint.getSignature();System.out.println("方法最终执行完毕-日志-方法名-" + signature.getName());}/*** 环绕通知* @param joinPoint* @return* @throws Throwable*/@Around("execution(public float com.sunxiansheng.myspring.aop.SmartDog.getSub(float, float))")public Object logMethodExecution(ProceedingJoinPoint joinPoint) throws Throwable {MethodSignature signature = (MethodSignature) joinPoint.getSignature();// 获取方法信息String methodName = signature.getMethod().getName();String className = signature.getDeclaringType().getSimpleName();System.out.println("环绕通知 method " + className + "." + methodName);// 获取目标对象Object targetObject = joinPoint.getTarget();// 环绕通知获取目标对象System.out.println("环绕通知获取目标对象:" + targetObject);try {// 前置通知:环绕通知获取参数System.out.println("环绕通知获取参数:" + Arrays.asList(joinPoint.getArgs()));Object result = joinPoint.proceed();  // 执行目标方法// 返回通知:环绕通知获取结果System.out.println("环绕通知获取结果:" + result);return result;} catch (Exception e) {// 异常通知throw e;} finally {// 最终通知System.out.println("环绕通知 method " + className + "." + methodName);}}}
5.beans.xml开启aop注解并扫描aop包

CleanShot 2024-08-04 at 15.19.30@2x

6.AppMain.java 测试AOP

CleanShot 2024-08-04 at 15.19.55@2x

CleanShot 2024-08-04 at 15.27.37@2x

6.简单分析AOP和后置处理器的关系

CleanShot 2024-08-04 at 15.41.14@2x

3.抛出问题

1.bean是怎么注入容器的?
2.为什么加了@Autowired就能被依赖注入?
3.单例多例是怎么实现的?
4.Bean的后置处理器是怎么实现的?
5.原生Spring的AOP是如何实现的?

4.将代码放到远程仓库

1.VCS -》 share

CleanShot 2024-08-04 at 14.44.28@2x

2.查看仓库

CleanShot 2024-08-04 at 14.45.31@2x

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

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

相关文章

掌握电子邮件的艺术:使用 Mailbird 统一管理您的数字生活

在数字时代&#xff0c;电子邮件已成为我们沟通的骨干。无论是商务交流、家庭联络&#xff0c;还是订阅更新&#xff0c;我们几乎每天都在使用电子邮件。但随着账户数量的增加&#xff0c;管理这些账户变得日益复杂。如何有效地整合和优化您的电子邮件体验&#xff1f;Mailbird…

【PaperInFive-时间序列预测】TSMixer:用于时间序列预测的全MLP架构(谷歌)

全文总结&#xff1a;本文研究了线性模型用于时间序列预测的能力&#xff0c;提出了时间序列混合器(TSMixer)&#xff0c;一种通过堆叠多层感知器(mlp)设计的新架构。TSMixer在时间和特征维度上交替应用mlp&#xff0c;在概念上对应于时间混合和特征混合操作&#xff0c;有效地…

AI开发者大赛 | 6道算法赛题上新

2024 AI开发者大赛正在如火如荼地进行着&#xff0c;本届比赛吸引了全球范围内的众多优秀开发者参与其中&#xff0c;用代码书写未来&#xff0c;用算法改变世界。 如今&#xff0c;算法赛新一批赛题上线&#xff0c;无论是初学者还是资深开发者&#xff0c;你都可以在2024 AI…

ClickHouse集群的安装

目录 1.clickhouse中文文档地址 2.centos安装部署 2.1采用tgz的方式安装 2.2修改配置文件 2.3修改数据目录 2.4创建角色和目录 3 集群安装 3.1配置文件修改 3.2启动zookeeper 3.3启动clickhouse-server 3.4任意节点连接clickhouse 3.5查看集群 3.6建库 3.7查看数…

了解住宅代理和移动代理的工作原理:从基础到高级应用

在当今时代&#xff0c;代理技术已经成为了优化网络连接、提升数据安全和增强用户体验的重要工具。特别是住宅代理和移动代理&#xff0c;这两种代理类型在网络服务中扮演着越来越重要的角色。本文将从详细的为您介绍这两种代理服务的工作原理&#xff0c;帮助你更好地理解并应…

如何对 GitLab 中文版进行升级?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;专门面向中国程序员和企业提供企业级一体化 DevOps 平台&#xff0c;用来帮助用户实现需求管理、源代码托管、CI/CD、安全合规&#xff0c;而且所有的操作都是在一个平台上进行&#xff0c;省事省心省钱。可以一键安装极狐GitL…

ArcGIS空间自相关 (Global Moran‘s I)——探究人口空间格局的20年变迁

先了解什么是莫兰指数&#xff1f; 莫兰指数&#xff08;Morans I&#xff09;是一种用于衡量空间自相关性的统计量&#xff0c;即它可以帮助我们了解一个地理区域内的观测值是否彼此相关以及这种相关性的强度和方向。 白话版&#xff1a;一句话就是判断数据在空间上有没有自…

Prometheus 和 Grafana 通过nginx-exporter监控nginx

在生产环境下&#xff0c;您已经部署了 Prometheus 和 Grafana&#xff0c;并希望通过它们来监控另一台 Ubuntu 20.04 上的 Nginx 服务。以下是配置步骤&#xff1a; 1. 安装和配置 nginx-exporter (Nginx 的 Prometheus 导出器) nginx-exporter 是 Prometheus 用来从 Nginx …

【机器学习-监督学习】逻辑斯谛回归

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科&#xff0c;通过算法和模型让计算机从数据中学习&#xff0c;进行模型训练和优化&#xff0c;做出预测、分类和决策支持。Python成为机器学习的首选语言&#xff0c;…

深度学习 --- VGG16各层feature map可视化(JupyterNotebook实战)

VGG16模块的可视化 VGG16简介&#xff1a; VGG是继AlexNet之后的后起之秀&#xff0c;相对于AlexNet他有如下特点&#xff1a; 1&#xff0c;更深的层数&#xff01;相对于仅有8层的AlexNet而言&#xff0c;VGG把层数增加到了16和19层。 2&#xff0c;更小的卷积核&#xff01;…

程序员如何平衡日常编码工作与提升式学习?

引言 在如今这个技术飞速发展的时代,程序员不仅需要专注于完成日常的编码任务,还必须不断提升自己的技能,以应对行业的变化和个人职业发展的需求。然而,在高强度的工作环境中,找到时间进行学习是一项挑战。许多程序员陷入了这样的困境:一方面,日常的编码工作要求高效且…

苹果手机照片格式heic怎么改jpg?教你3招快速转换

苹果手机照片格式heic怎么改jpg&#xff1f;将苹果手机照片格式从HEIC转为JPG&#xff0c;在日常使用中带来了极大便利。HEIC格式虽高效节省空间&#xff0c;但兼容性不如JPG广泛。转为JPG后&#xff0c;照片能轻松在多数设备、软件和在线平台上分享、打印或编辑&#xff0c;无…

【论文阅读】A Closer Look at Parameter-Efficient Tuning in Diffusion Models

Abstract 大规模扩散模型功能强大&#xff0c;但微调定制这些模型&#xff0c;内存和时间效率都很低。 本文通过向大规模扩散模型中插入小的学习器(称为adapters)&#xff0c;实现有效的参数微调。 特别地&#xff0c;将适配器的设计空间分解为输入位置、输出位置、函数形式的…

探索Python的自动化魔法:AutoIt库揭秘

文章目录 探索Python的自动化魔法&#xff1a;AutoIt库揭秘第一部分&#xff1a;背景介绍第二部分&#xff1a;AutoIt是什么&#xff1f;第三部分&#xff1a;如何安装AutoIt库&#xff1f;第四部分&#xff1a;AutoIt的五个简单函数第五部分&#xff1a;场景应用第六部分&…

Pod基础使用

POD基本操作 1.Pod生命周期 在Kubernetes中&#xff0c;Pod的生命周期经历了几个重要的阶段。下面是Pod生命周期的详细介绍&#xff1a; Pending&#xff08;待处理&#xff09;: 调度: Pod被创建后&#xff0c;首先进入“Pending”状态。此时&#xff0c;Kubernetes的调度器…

云计算产业链图谱_产业链全景图_云计算行业市场分析

在产业数字化转型的背景下&#xff0c;云计算作为信息技术的重要组成部分&#xff0c;正逐渐成为各行业数字化、智能化转型的关键支撑。受益于5G、大数据、物联网、人工智能等技术的快速发展&#xff0c;云计算产业规模持续扩大&#xff0c;市场需求不断增长。云计算作为一种新…

C语言 | Leetcode C语言题解之第367题有效的完全平方数

题目&#xff1a; 题解&#xff1a; bool isPerfectSquare(int num) {long long left0;long long rightnum;while(left<right){long long mid(leftright)/2;long long ansmid*mid;if(ans<num){leftmid1;}else if(ans>num){rightmid-1;}else{return true;}}return…

书生模型实战L1---OpenCompass 评测

书生模型实战系列文章目录 第一章 入门岛L0&#xff08;Linux&#xff09; 第二章 入门岛L0&#xff08;python&#xff09; 第三章 入门岛L0&#xff08;Git&#xff09; 第四章 基础岛L1&#xff08;书生全链路开源介绍&#xff09; 第五章 基础岛L1&#xff08;Demo&#x…

打卡学习Python爬虫第五天|使用Xpath爬取豆瓣电影评分

思路&#xff1a;使用Xpath爬取豆瓣即将上映的电影评分&#xff0c;首先获取要爬取页面的url&#xff0c;查看页面源代码是否有我们想要的数据&#xff0c;如果有&#xff0c;直接获取HTML文件后解析HTML内容就能提取出我们想要的数据。如果没有则需要用到浏览器抓包工具&#…

网络初识部分

1.网络 单机时代-局域网时代-广域网时代-移动互联网时代 局域网时代&#xff1a;通过路由器把几个电脑连接起来。 广域网时代&#xff1a;把更多的局域网连接到一起&#xff0c;构成的网络更庞大&#xff0c;可能已经覆盖了一个城市/国家/全世界。 2.什么是路由器&#xff…