Spring核心原理解析

news2024/11/17 2:41:55

1.Bean的生命周期底层原理

AppConfig

package com.zhouyu;

import com.zhouyu.service.OrderService;
import org.springframework.context.annotation.*;

@ComponentScan("com.zhouyu")
public class AppConfig {

	@Bean
	public OrderService orderService1(){
		return new OrderService();
	}

	@Bean
	public OrderService orderService2(){
		return new OrderService();
	}

}

OrderService

package com.zhouyu.service;

import org.springframework.stereotype.Component;

@Component
public class OrderService {

}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
说明:在spring容器中存在多个bean对象时,bean在无参构造方法中引入某个bean,更改参数名称决定具体引入那一个bean,当参数的名称在bean中不存在时,此时程序就会报错。

2.依赖注入底层原理

2.1 通过spring.xml方式进行注入

spring.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"
	   xmlns:aop="http://www.springframework.org/schema/aop"
	   xsi:schemaLocation="http://www.springframework.org/schema/beans
	   https://www.springframework.org/schema/beans/spring-beans.xsd
	   http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"
	   >

	<context:component-scan base-package="com.zhouyu"/>



	<bean id="user1" class="com.zhouyu.service.User" scope="prototype"/>

	<bean id="user2" class="com.zhouyu.service.User" parent="user1"/>
</beans>

java获取对象

package com.zhouyu;

import com.zhouyu.service.User;
import com.zhouyu.service.UserService;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.springframework.aop.Pointcut;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.aop.support.AbstractPointcutAdvisor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodProxy;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.annotation.PostConstruct;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class Test {

	public static void main(String[] args) {

		ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("spring.xml");
		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();

	}
}

2.2 通过注解方式进行注入

AppConfig

package com.zhouyu;

import org.springframework.context.annotation.*;
import org.springframework.scheduling.annotation.EnableScheduling;

@ComponentScan("com.zhouyu")
@EnableScheduling
@PropertySource("classpath:spring.properties")
public class AppConfig {
	
}

java获取对象

package com.zhouyu;

import com.zhouyu.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test {

	public static void main(String[] args) {
		
		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);

		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();
	}
}

说明:spring通过解析appConfig.class得到扫描路径,然后遍历该路径下的含有@Component、@Service注解对象记录下来,放在一个map集合中,通过beanName作为key,当前类作为value。

3.初始化底层原理

3.1 初始化前

User对象

package com.zhouyu.service;

import org.springframework.stereotype.Component;

@Component
public class User {
	private String name;
	private String password;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}
}

UserService 对象的test方法

package com.zhouyu.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Date;

@Component
public class UserService{

    @Autowired
	private OrderService orderService;

	@Autowired
    private User admin;



	public void test(){
       System.out.println(admin.getName());
	}


	@PostConstruct
	public User getAdmin(){
		admin.setPassword("123");
		admin.setName("LiMing");
		return admin;
	}

}

在这里插入图片描述

在这里插入图片描述

说明:User对象必须加上Component注解,这样才能被Spring容器进行管理,此时在getAdmin方法中加上PostConstruct注解后,此时对admin进行赋值,才其他方法中就能获取admin赋值的对象。

3.2 初始化

package com.zhouyu.service;

import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.Date;

@Component
public class UserService implements InitializingBean{

    @Autowired
	private OrderService orderService;

	@Autowired
	private User user;



	public void test(){
       System.out.println(user);
	}


	@Override
	public void afterPropertiesSet() throws Exception {
		user.setPassword("123");
		user.setName("LiMing");
	}
}

在这里插入图片描述

说明:初始化时,查看方法是否实现了InitializingBean接口,假如实现了该方法,将会执行afterPropertiesSet方法。

3.3 初始化后实现AOP

ZhouyuAspect.java对象

package com.zhouyu.aspect;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class ZhouyuAspect {

	@Before("execution(public void com.zhouyu.service.UserService.test())")
	public void a(){
        System.out.println("test Before");
	}

	@After("execution(public void com.zhouyu.service.UserService.test())")
	public void b(){
		System.out.println("test After");
	}



}

test.java对象

package com.zhouyu;


import com.zhouyu.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;


import java.lang.reflect.InvocationTargetException;


public class Test {

	public static void main(String[] args) throws InvocationTargetException, IllegalAccessException {

		// 创建一个Spring容器
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class);


		UserService userService = (UserService) applicationContext.getBean("userService");
		userService.test();


	}
}

UserService.java对象

package com.zhouyu.service;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserService implements InitializingBean{

    @Autowired
	private OrderService orderService;

	@Autowired
    private User admin;



	public void test(){
       System.out.println(admin.getName());
	}

	@Override
	public void afterPropertiesSet() throws Exception {
		admin.setName("LiMing123");
		admin.setPassword("123");
	}
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

说明:当引用切面后,userService将会在底层生成一个userServiceProxy代理方法,代理对象此时也有test方法,在执行test方法之前执行切面@before方法,然后执行test方法,test方法将会调用父类里面test方法,所有当进去test方法里面时,此时属性又有值了。

4.推断构造方法底层原理

存在多个构造方法,其中一个是无参构造方法
在这里插入图片描述
存在多个构造方法,无无参构造方法
在这里插入图片描述
存在多个构造方法,其中一个构造方法含有Autowired注解
在这里插入图片描述
说明:创建对象时,通过该类的构造方法进行创建对象,假如该类只有一个构造方法时候,就采用这个构造方法,假如有多个构造方法,存在无参构造方法就用无参构造方法进行构造,假如不存在无参构造方法,存在多个有参构造方法就会报错,但是存在多个有参构造方法,其中一个构造方法有@Autowired,将会采用这个构造方法。同时也会判断是否有被Autowired注解的属性,有的话也会把属性找出来并由spring进行赋值。

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

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

相关文章

微机实验一:认识实验系统和联机通讯实验

实验目的 讲清楚进行本实验后要学到的知识、掌握的数据结构及共定义和农示方法&#xff0c;讲清楚所采用的算法 wrTPL-486微机原理及接口技术数学实验手统的操u)孰秀TPC-480联机集闯开发调试故件的操作环境3)3俩文丝计体机的基阻成和4、存储器并有接新i的置(了解岗单汇海语谢设…

Nginx【location指令、虚拟主机的分类、Nginx支持三种类型的虚拟主机配置 】(三)-全面详解(学习总结---从入门到深化)

目录 Nginx配置指令详解_location指令 虚拟主机的分类 Nginx支持三种类型的虚拟主机配置 Nginx配置指令详解_location指令 配置location块 语法&#xff1a; URL // http://ip:port/ location [ | ~ | ~* | ^~] uri {... } 示例1 没有修饰符 表示&#xff1a;必须以指…

UE5 MetaHuman SDK插件的使用【二、聊天机器人】

目录 制作&#xff1a; 流程制作【相对复杂但逻辑清楚】&#xff1a; 快速制作【有个函数把上面的流程全部合在了一起&#xff0c;只需要用一个函数即可】 3个结构体的参数 combo后面的逻辑&#xff1a; 效果&#xff1a; ​编辑 代码 在前面的文章中&#xff0c;我们创…

geoserver发布arcgis server离线瓦片

1.使用tif文件也可以发布服务&#xff0c;但是我下载的tif文件发布的服务总数模糊不清&#xff0c;原因可能是地图比例尺问题。 2.仔细研究&#xff0c;发现下载的arcgis server瓦片都是高清的&#xff0c;于是想到直接加载arcgis瓦片&#xff0c;这样图片/坐标系之间问题都完…

Python3 实例(四) | 菜鸟教程(二十二)

目录 一、Python 堆排序 二、Python 计数排序 三、Python 希尔排序 四、Python 拓扑排序 五、Python 简单的银行系统 一、Python 堆排序 &#xff08;一&#xff09;堆排序&#xff08;Heapsort&#xff09;是指利用堆这种数据结构所设计的一种排序算法。 &#xff08;二…

【JUC-6】AQS介绍,基于AQS实现自己的锁

什么是AQS AbstractQueuedSynchronizer(抽象队列同步器&#xff0c;简称AQS)出现在JDK 1.5中。AQS是很多同步器的基础框架&#xff0c;比如ReentrantLock、CountDownLatch和Semaphore等都是基于AQS实现的。除此之外&#xff0c;我们还可以基于AQS&#xff0c;定制出我们所需要…

关于LiveData全面详解(附事件总线)

前言&#xff1a;缤纷色彩闪出的美丽 是因它没有 分开每种色彩 前言 MVVM 架构模式中&#xff0c;ViewModel 是不会持有宿主的信息&#xff0c;业务逻辑在 ViewModels 层中完成&#xff0c;而不是在 Activities 或 Fragments 中。LiveData 在里面担任数据驱动的作用&#xff1…

ElementPlus的Collapse 折叠面板问题

我也不明白为什么会报这个错误&#xff0c;把关于ts的代码改成js的就可以了。。 ERROR in ./src/views/Home.vue?vue&typescript&langts&setuptrue (./node_modules/vue-loader/dist/index.js??ruleSet[0].use[0]!./src/views/Home.vue?vue&typescript&…

大厂经验,基于资产健康度量化的小米数据治理实践

摘要&#xff1a;随着小米公司各项业务的快速发展&#xff0c;数据中的商业价值也愈发突显。而与此同时&#xff0c;各业务团队在数据查询、分析等方面的压力同样正在剧增。小米大数据团队用大数据管理大数据&#xff0c;从存储、计算、规范、质量、安全五方面着手治理&#xf…

java swing实现JTextField文本框的输入提示补全功能,以登陆界面自动提示补全用户账号为例,自动填充账号密码

前言 如果您想了解更多的java项目功能源码,请订阅我的专栏: java项目源码合集100+ 一、实现的功能 在使用java做界面实现输入功能的时候,使用了JTextField文本输入组件,希望能够根据用户的输入,自动提示,之后用户可以选择提示的内容作为文本框的输入内容,效果如下: 当…

Java中的阻塞队列使用以及详解

文章目录 一、Queue接口1. 常见方法以及功能(不具有阻塞队列特性)1.1 add(E e)1.2. offer():1.3. remove()1.4. poll()1.5. element()1.6. peek() 2. add和offer对比&#xff1a;3. remove和poll对比&#xff1a;4. element#peek方法对比&#xff1a; 二、BlockingQueue阻塞队列…

MySQL:子查询(全面详解)

MySQL&#xff1a;子查询 前言一、需求分析与问题解决1、实际问题2、子查询的基本使用3、子查询的分类 二、单行子查询1、单行比较操作符2、代码示例3、HAVING 中的子查询4、CASE中的子查询5、子查询中的空值问题6、非法使用子查询 三、多行子查询1、多行比较操作符2、代码示例…

Unity VR 开发教程 OpenXR+XR Interaction Toolkit(八)手指触控 Poke Interaction

文章目录 &#x1f4d5;教程说明&#x1f4d5;XR Poke Interactor&#x1f4d5;与 UI 进行触控交互⭐添加 Tracked Device Graphic Raycaster 和 XR UI Input Module 让 UI 可被交互 &#x1f4d5;与物体进行交互⭐XR Simple Interactable⭐XR Poke Filter 往期回顾&#xff1a…

偏爱console.log的你,肯定会觉得这个插件泰裤辣!

前言 毋庸置疑&#xff0c;要说前端调试代码用的最多的&#xff0c;肯定是console.log&#xff0c;虽然我现在 debugger 用的比较多&#xff0c;但对于生产环境、小程序真机调试&#xff0c;还是需要用到 log 来查看变量值&#xff0c;比如我下午遇到个场景&#xff1a;选择完…

单片机-串口通信

1.串口向电脑发送数据 1.配置串口 T1定时器&#xff0c;方式二8位重装 void UartInit(void) //4800bps11.0592MHz {PCON & 0x7F; //波特率不倍速SCON 0x50; //8位数据,可变波特率TMOD & 0x0F; //清除定时器1模式位TMOD | 0x20; //设定定时器1为8位自动重装方式…

Win11桌面右键菜单怎么变成老版本?

Win11桌面右键菜单怎么变成老版本&#xff1f;Win11系统带来了许多新的功能和改进&#xff0c;其中一个显著的变化是Win11桌面右键菜单的设计和布局&#xff0c;所以有些用户就想把Win11桌面右键菜单变成老版本&#xff0c;那具体怎么操作&#xff0c;可以按照以下小编分享的方…

chatgpt赋能python:用Python关机:简单、快捷、高效的关机方式

用Python关机&#xff1a;简单、快捷、高效的关机方式 介绍 在我们使用计算机的日常生活中&#xff0c;关机是必不可少的一个要素。传统的关机方式通常是通过点击“开始”菜单——“关机”按钮来完成的。但是&#xff0c;使用Python可以让我们更加方便和高效地完成关机操作。…

海外媒体发稿:海外新闻发表文章的必要性

海外新闻发表文章&#xff0c;是指国外企业在当地新闻媒体上发表企业信息和企业企业形象活动&#xff0c;通过专业媒体网络资源&#xff0c;依靠技术专业的报道发稿平台&#xff0c;让国外企业迅速、精确、低成本开展海外新闻稿子的出台&#xff0c;根据媒体报导&#xff0c;提…

PyQt5入门1——PyQt5的安装与Hello World应用

PyQt5入门1——PyQt5的安装与Hello World应用 学习前言简介&#xff08;From 百度百科&#xff09;安装Hello World1、窗口构建a、构建基础类b、编写UI 2、主程序运行 全部代码 学习前言 搞搞可视化界面哈&#xff0c;虽然不一定有用&#xff0c;但是搞一下。 简介&#xff…

Makefile实战

文章目录 1、准备环境1.2、规则1.3、假目标1.4、变量1.5、自动变量1.6、函数addprefix 函数filter函数filter-out函数patsubst函数strip函数wildcard函数 1、准备环境 准备一台Linux机器&#xff0c;验证环境中是否呗正确安装了&#xff0c;使用make -v命令进行验证 1.2、规则 …