1.Spring底层源码解读课程安排
2.Springxml、注解实现IOC区别
3.简单模拟手写出xml方式实现IOC
4.简单模拟手写出注解方式实现IOC
2022版本Spring5深入源码解读 | |
---|---|
Spring5源码分析之IOC原理 | 掌握Spring5的源码正确阅读方式、bean对象创建与初始化、一步一步手绘spring源码架构图 |
Spring5源码分析之IOC原理 | 掌握BeanFactory与FactoryBean原理分析、后置处理器增强、Bean的生命周期源码分析监听器与事件监听事件机制源码分析 |
Spring5源码分析之循环依赖 | 掌握怎么检测循环依赖、怎么解决循环依赖、循环依赖无法解决的场景、三级与二级缓存设计 |
Spring5源码分析之AOP原理 | 掌握手绘Aop流程架构图、Aop调用链、动态代理模式应用、事务失效之谜与底层实现 |
Spring5源码分析之AOP原理 | 掌握Spring5的高级应用、巧妙的运用在工作中、经典Spring面试题 |
Spring5源码分析之事务原理 | 掌握PlatformTransactionManager、TransactionManager、传播行为原理 |
SpringMVC源码分析之SpringMVC请求处理流程 | 掌握SpringMVC请求处理流程、SpringMVC的工作机制、DispatcherServlet |
SpringMVC源码分析之SpringMVC请求处理流程 | 掌握SpringMVC请求的时候是如何找到正确的Controller、Controller的方法中参数的工作原理 |
SpringMVC源码分析之SpringMVC请求处理流程 | 掌握json、xml自动转换的原理研究、类型转换、数据绑定详解、MVC拦截器详解、MVC视图机制详解、异常处理机制详解 |
SpringBoot源码解读之启动原理分析 | 掌握@EnableAutoConfiguration @SpringBootApplication、Springboot自动装配的实现原理 |
SpringBoot源码解读之自定义starter组件 | 掌握SpringBoot自定义starter组件原理 |
Spring 配置bean方式
方式1 xml方式
方式2 注解方式
SpringBoot 底层 基于 Spring注解封装
<dependencies>
<dependency>
<groupId>dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>1.6.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/jaxen/jaxen -->
<dependency>
<groupId>jaxen</groupId>
<artifactId>jaxen</artifactId>
<version>1.2.0</version>
</dependency>
<!-- 反射框架 -->
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>0.9.11</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--
配置SpringBean对象
-->
<bean id="userEntity" class="com.mayikt.entity.UserEntity"></bean>
<bean id="mayiktService" class="com.mayikt.service.MayiktService"></bean>
</beans>
package com.mayikt.test;
import com.mayikt.entity.UserEntity;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @author 余胜军
* @ClassName Test01
* @qq 644064779
* @addres www.mayikt.com
* 微信:yushengjun644
*/
public class Test01 {
public static void main(String[] args) {
//1.读取spring.xml
ClassPathXmlApplicationContext classPathXmlApplicationContext =
new ClassPathXmlApplicationContext("spring.xml");
//2.从IOC容器读取到userEntity
UserEntity userEntity =
classPathXmlApplicationContext.getBean("userEntity", UserEntity.class);
System.out.println(userEntity);
}
}
package com.mayikt.config;
import com.mayikt.entity.UserEntity;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @author songchuanfu
* @qq 1802284273
*/
@Configuration
@ComponentScan("com.mayikt.service")
public class MayiktConfig {
@Bean("user")
public UserEntity userEntity() {
return new UserEntity();
}
}
package com.mayikt.test;
import com.mayikt.config.MayiktConfig;
import com.mayikt.entity.UserEntity;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @author songchuanfu
* @qq 1802284273
*/
public class Test02 {
public static void main(String[] args) {
//加载MayiktConfig.class
AnnotationConfigApplicationContext mayiktConfig
= new AnnotationConfigApplicationContext(MayiktConfig.class);
// 获取userEntity
UserEntity userEntity = mayiktConfig.getBean("userEntity", UserEntity.class);
System.out.println(userEntity);
}
}
SpringIOC容器底层实现原理:
反射+工厂模式+解析xml技术实现
1.使用解析xml技术 解析spring.xml配置文件;
2.获取 类的完整路径地址
3.使用到反射技术初始化对象
4.需要使用工厂模式封装初始化对象
package com.mayikt.ext;
import com.mayikt.entity.UserEntity;
import com.mayikt.service.MayiktService;
import org.dom4j.*;
import org.dom4j.io.SAXReader;
import org.springframework.core.io.ClassPathResource;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author songchuanfu
* @qq 1802284273
*/
public class SpringIOCXml {
private ConcurrentHashMap<String, Object> beansHashMap = new ConcurrentHashMap<>();
public SpringIOCXml() throws IOException, DocumentException {
// 初始化IOC容器
initIoc();
}
public <T> T getBean(String name, Class<T> requiredType) {
Object o = beansHashMap.get(name);
return (T) o;
}
private void initIoc() throws IOException, DocumentException {
//1.解析xml配置
ClassPathResource classPathResource = new ClassPathResource("spring.xml");
File xmlFile = classPathResource.getFile();
SAXReader saxReader = new SAXReader();
Document doc = saxReader.read(xmlFile);
// 获取到根节点
Element rootElement = doc.getRootElement();
List<Element> beans = rootElement.elements("bean");
beans.forEach((bean -> {
try {
//2.查找
//3.利用反射机制初始化 class="com.mayikt.entity.UserEntity" 将bean对象存入Map集合中
String beanIdStr = bean.attribute("id").getValue();
String classStr = bean.attribute("class").getValue();
Class<?> bClass = Class.forName(classStr);
Object object = bClass.newInstance();
beansHashMap.put(beanIdStr, object);
} catch (Exception e) {
}
}));
}
public static void main(String[] args) throws DocumentException, IOException {
SpringIOCXml springIOCXml = new SpringIOCXml();
UserEntity userEntity = springIOCXml.getBean("userEntity", UserEntity.class);
MayiktService mayiktService = springIOCXml.getBean("mayiktService", MayiktService.class);
mayiktService.add();
}
}
思路:
1.ioc容器底层核心 HashMap集合 (key=beanid value=bean对象)
user()
beanid:user bean对象 new UserEntity();
HashMap.put(user ,new UserEntity());
getBean("user ")-----new UserEntity()
1.将spring.xml配置文件读取到程序中
2.利用解析xml框架spring.xml
3.获取(bean标签)节点 beanid ====HashMap.key value 利用反射机制初始化
com.mayikt.service.OrderService
@ComponentScan(“com.mayikt.service”)
1.利用java反射机制获取到该包下所有的类(class)
2.利用java反射机制 判断每个类上是否有加上@Component
3.如果有加上该注解的情况下 类的名称 首字母变成小写 作为bean的id value
该类class 利用反射初始化
4.存入到map集合中。
1.使用@Bean注解 ----没有反射初始化对象 根据方法返回值 作为 bean对象
2.@ComponentScan 底层 使用反射初始化对象
3.xml
package com.mayikt.ext;
import com.mayikt.config.MayiktConfig;
import com.mayikt.entity.UserEntity;
import com.mayikt.service.MayiktService;
import com.mayikt.service.OrderService;
import com.mayikt.utils.ClassUtils;
import org.reflections.Reflections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.concurrent.ConcurrentHashMap;
/**
* @author songchuanfu
* @qq 1802284273
*/
public class SpringIOCAnnotation {
private Object config;
private ConcurrentHashMap<String, Object> beansHashMap = new ConcurrentHashMap<>();
/**
* 传递配置类
*/
public SpringIOCAnnotation(Object config) {
this.config = config;
initIoc();
}
/**
* 初始化IOC容器
*/
public void initIoc() {
Configuration configuration
= this.config.getClass().getDeclaredAnnotation(Configuration.class);
if (configuration == null) {
return;
}
// 如果该类上有配置configuration
// 利用java反射机制
Class<?> aClass = config.getClass();
Method[] declaredMethods = aClass.getDeclaredMethods();
Arrays.stream(declaredMethods).forEach(m -> {
Bean bean = m.getDeclaredAnnotation(Bean.class);
if (bean != null) {
try {
// 方法名称作为bean的id
String[] value = bean.value();
String beanId = value[0];
String defBeanId = m.getName();
// 获取方法返回值
Object result = m.invoke(config, null);
beansHashMap.put(StringUtils.isEmpty(beanId) ? defBeanId : beanId, result);
} catch (Exception e) {
}
}
});
//ComponentScan
//利用反射机制查找 该包下所有的class
ComponentScan componentScan = aClass.getDeclaredAnnotation(ComponentScan.class);
if (componentScan != null) {
String[] strings = componentScan.value();
Arrays.stream(strings).forEach(pack -> {
Class[] classByPackage = ClassUtils.getClassByPackage(pack);
Arrays.stream(classByPackage).forEach(c -> {
Annotation component = c.getDeclaredAnnotation(Component.class);
if (component != null) {
try {
// 注入到ioc容器中
String beanId = c.getSimpleName();
Object beanObject = c.newInstance();
beansHashMap.put(beanId, beanObject);
} catch (Exception e) {
}
}
});
});
}
}
public <T> T getBean(String name, Class<T> requiredType) {
Object o = beansHashMap.get(name);
return (T) o;
}
public static void main(String[] args) {
SpringIOCAnnotation springIOCAnnotation =
new SpringIOCAnnotation(new MayiktConfig());
OrderService orderService =
springIOCAnnotation.getBean("OrderService", OrderService.class);
System.out.println(orderService);
}
}
spring源码day01.rar