spring之HelloWord版

devtools/2024/10/22 16:44:29/

目录

基础结构说明

涉及到的功能

执行流程

spring%E5%8C%85-toc" style="margin-left:40px;">spring

引导类

bean定义

注解

回调接口拓展

测试入口

service包

回调接口拓展实现

实体类

自定义注解


基础结构说明

  1. spring子包内,放置spring源码相关类,如注解定义,引导类执行逻辑等

  2. service子包,放置测试类,用于测试spring相关功能,如实体类、自主实现的后处理拓展等

涉及到的功能

  1. componentscan扫描包

  2. component bean注入

  3. Scope bean作用域

  4. beanDefintion bean定义对象

  5. beanDefintionMap bean定义对象集合

  6. getBean 获取容器bean

  7. createBean 创建容器bean

  8. autowird 依赖注入

  9. BeanNameAware 初始化阶段回调拓展

  10. initializingBean 初始化后回调拓展

  11. beanPostProcess bean后置处理器拓展

    1. AOP

    2. vaulue注入

执行流程

引导类构造器(启动入口)

  1. scan扫描(装配BDMap)

    1. 获取引导配置类的扫描注解的路径

    2. 解析处理路径获取类路径下的所有类资源

    3. 遍历所有类

      1. 处理类的相对路径,通过类加载器获取类的class对象

      2. 处理component注解获取beanname

        1. 扫描当前类如果实现了bean后置处理器则加入list

      3. 处理scope注解默认单例

      4. 组装beandeftion对象,组装beanDefinitionMap

  2. 遍历bdMap创建单例对象 多例直接获取的时候创建

    1. createBean创建bean,使用反射获取无参构造器获取对象

    2. aware拓展BeanNameAware拓展 bean初始化的阶段生效

    3. BeanPostProcessor拓展,before处理

    4. InitializingBean初始化后拓展

    5. BeanPostProcessor拓展,after处理

  3. 创建好的bean加入单例池

spring%E5%8C%85">spring

引导类

java">package com.spring;import com.butch.AppConfig;import java.beans.Introspector;
import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;//相当于引导类
public class ButchSpringApplicationContext {private Class configClass;private Map<String, BeanDefinition> beanDefinitionMap = new HashMap();//单例池private Map<String, Object> singletonObjects = new HashMap();private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();//构造器进入spring的启动流程public ButchSpringApplicationContext(Class configClass){this.configClass = configClass;//开启扫描包scan(configClass);//遍历bdMap 创建单例对象 多例直接获取的时候创建for (Map.Entry<String,BeanDefinition> map : beanDefinitionMap.entrySet()) {String beanName = map.getKey();BeanDefinition beanDefinition = map.getValue();if ("singleton".equals(beanDefinition.getScope())){Object bean = createBean(beanName, beanDefinition);singletonObjects.put(beanName,bean);}}}//创建Beanprivate Object createBean(String beanName, BeanDefinition beanDefinition) {//使用反射Class type = beanDefinition.getType();Object instance = null;try {instance = type.getConstructor().newInstance();//处理依赖注入Field[] declaredFields = type.getDeclaredFields();//遍历该类所有属性 是否加了依赖注入注解for (Field declaredField : declaredFields) {if (declaredField.isAnnotationPresent(Autowired.class)){//进行依赖注入declaredField.setAccessible(true);declaredField.set(instance,getBean(declaredField.getName()));}}//BeanNameAware拓展 bean初始化的阶段生效if (instance instanceof BeanNameAware){((BeanNameAware) instance).setBeanName(beanName);}//后置处理器前扩展for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {beanPostProcessor.postProcessBeforeInitialization(instance,beanName);}if (instance instanceof InitializingBean){((InitializingBean) instance).afterPropertiesSet();}//后置处理器后扩展for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {instance = beanPostProcessor.postProcessAfterInitialization(instance,beanName);}} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} catch (InvocationTargetException e) {e.printStackTrace();} catch (NoSuchMethodException e) {e.printStackTrace();}return instance;}//getbean方法public Object getBean(String beanName){//主要根据BDMap判断获取if (!beanDefinitionMap.containsKey(beanName)){throw new NullPointerException();}BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);//区分单例多例if ("singleton".equals(beanDefinition.getScope())){//单例直接从单例池获取Object singletonBean = singletonObjects.get(beanName);if (singletonBean == null){singletonBean = createBean(beanName,beanDefinition);singletonObjects.put(beanName,singletonBean);}return singletonBean;}else {//多例直接创建return createBean(beanName, beanDefinition);}}private void scan(Class configClass){//获取配置类的注解if (configClass.isAnnotationPresent(ComponentScan.class)){ComponentScan componentScan = (ComponentScan) configClass.getAnnotation(ComponentScan.class);//处理注解的value路径String path = componentScan.value();path = path.replaceAll("\\.","/");System.out.println("path = " + path);//获取应用类加载器ClassLoader classLoader = ButchSpringApplicationContext.class.getClassLoader();//获取路径下的资源URL resource = classLoader.getResource(path);//处理资源文件File file = new File(resource.getFile());if (file.isDirectory()){for (File o : file.listFiles()) {String absolutePath = o.getAbsolutePath();//处理类路径 absolutePath = com.butch.serivce.UserServiceabsolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));absolutePath = absolutePath.replace("\\", ".");System.out.println("absolutePath = " + absolutePath);//开始装配有component注解的对象try {//通过应用类加载器获取类的class对象Class<?> aClass = classLoader.loadClass(absolutePath);if (aClass.isAnnotationPresent(Component.class)) {//加入自主实现的后置处理器if (BeanPostProcessor.class.isAssignableFrom(aClass)){BeanPostProcessor beanPostProcessor = (BeanPostProcessor) aClass.getConstructor().newInstance();beanPostProcessorList.add(beanPostProcessor);}Component annotation = aClass.getAnnotation(Component.class);//获取beannameString beanName = annotation.value();if ("".equals(beanName)) {//jdk提供的默认beanNamebeanName = Introspector.decapitalize(aClass.getSimpleName());}BeanDefinition beanDefinition = new BeanDefinition();beanDefinition.setType(aClass);//处理bean是否单例if (aClass.isAnnotationPresent(Scope.class)) {Scope scope = aClass.getAnnotation(Scope.class);String value = scope.value();beanDefinition.setScope(value);} else {//默认单例beanDefinition.setScope("singleton");}//放入bean定义mapbeanDefinitionMap.put(beanName, beanDefinition);}}catch (Exception e){e.printStackTrace();}}}}}}

bean定义

java">package com.spring;/*** bean定义对象 存放一些bean的公共属性*/
public class BeanDefinition {private Class type;private String scope;private boolean isLazy;public Class getType() {return type;}public void setType(Class type) {this.type = type;}public String getScope() {return scope;}public void setScope(String scope) {this.scope = scope;}public boolean isLazy() {return isLazy;}public void setLazy(boolean lazy) {isLazy = lazy;}
}

注解

java">package com.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;//依赖注入
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {}
java">package com.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {String value() default "";}
java">package com.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {String value() default "";}

 

java">package com.spring;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {String value() default "";}

回调接口拓展

java">package com.spring;public interface BeanNameAware {void setBeanName(String name);
}
java">package com.spring;//bean后置处理器
public interface BeanPostProcessor {default Object postProcessBeforeInitialization(Object bean, String beanName) {return bean;}default Object postProcessAfterInitialization(Object bean, String beanName) {return bean;}
}
java">package com.spring;//初始化后
public interface InitializingBean {void afterPropertiesSet();
}

测试入口

java">package com.butch;import com.butch.serivce.UserInterface;
import com.spring.ButchSpringApplicationContext;public class TestSpring {public static void main(String[] args) {//开启扫描配置类 -> 创建单例beanButchSpringApplicationContext butchSpringApplication = new ButchSpringApplicationContext(AppConfig.class);UserInterface userService = (UserInterface) butchSpringApplication.getBean("userService");userService.test();}
}

 

java">package com.butch;import com.spring.ComponentScan;@ComponentScan("com.butch.serivce")
public class AppConfig {}

service包

回调接口拓展实现

java">package com.butch.serivce;public interface UserInterface {public void test();
}
java">package com.butch.serivce;import com.spring.BeanPostProcessor;
import com.spring.Component;import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//使用jdk代理实现一个aop
@Component
public class ButchBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessAfterInitialization(Object bean, String beanName) {if ("userService".equals(beanName)){Object proxyInstance = Proxy.newProxyInstance(ButchBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("==========beanPostProcessAop================");Object invoke = method.invoke(bean, args);return invoke;}});return proxyInstance;}return bean;}
}
java">package com.butch.serivce;import com.spring.BeanPostProcessor;
import com.spring.Component;import java.lang.reflect.Field;//注入后置处理
@Component
public class ButchValueBeanPostProcessor implements BeanPostProcessor {@Overridepublic Object postProcessBeforeInitialization(Object bean, String beanName) {for (Field field : bean.getClass().getDeclaredFields()) {//查看bean属性是否有value注解if (field.isAnnotationPresent(ButchValue.class)){//注入值field.setAccessible(true);try {field.set(bean,field.getAnnotation(ButchValue.class).value());} catch (IllegalAccessException e) {e.printStackTrace();}}}return bean;}
}

 

实体类

java">package com.butch.serivce;import com.spring.*;/***/
@Component
@Scope
public class UserService implements BeanNameAware,UserInterface,InitializingBean{@Overridepublic void afterPropertiesSet() {System.out.println("==========InitializingBean==========初始化后处理");}@Autowiredprivate OrderService orderService;@ButchValue("butch")private String name;public void test() {System.out.println("===============orderService============" + orderService + "=============" + name);}public void setBeanName(String name) {System.out.println("============BeanNameAwar==========" + name);}
}
java">package com.butch.serivce;import com.spring.Component;/***/@Component
public class OrderService {public void test() {System.out.println("test");}
}

自定义注解

java">package com.butch.serivce;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ButchValue {String value() default "";
}


http://www.ppmy.cn/devtools/57018.html

相关文章

2-17 基于matlab的改进的遗传算法(IGA)对城市交通信号优化分析

基于matlab的改进的遗传算法&#xff08;IGA&#xff09;对城市交通信号优化分析。根据交通流量以及饱和流量&#xff0c;对城市道路交叉口交通信号灯实施合理优化控制&#xff0c;考虑到交通状况的动态变化&#xff0c;及每个交叉口的唯一性。通过实时监测交通流量&#xff0c…

【Kali-linux for WSL】图形化界面安装

文章目录 前言图形化界面安装 前言 之前在WSL中安装了Kali 启动之后发现什么都没有&#xff01;&#xff01;&#xff01; 那我还怎么学习渗透技术&#xff1f;&#xff1f;&#xff1f; 看来&#xff0c;得改进下我的kali-linux for wsl&#xff0c;安装个图形化界面 图形化…

[图解]SysML和EA建模住宅安全系统-08-安全企业用例图

1 00:00:02,570 --> 00:00:04,400 接下来&#xff0c;我们就来画一下 2 00:00:06,770 --> 00:00:11,490 安全企业组织的用例图&#xff0c;画在哪里 3 00:00:11,760 --> 00:00:15,320 它是在3-用例这个包下面 4 00:00:15,690 --> 00:00:17,080 这是包的名字 5 …

layui-页面布局

1.布局容器 分为固定和完整宽度 class layui-container 是固定宽度 layui-fluid是完整宽度

二叉树的层序遍历/后序遍历(leetcode104二叉树的最大深度、111二叉树的最小深度)(华为OD悄悄话、数组二叉树)

104二叉树的最大深度 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 本题可以使用前序&#xff08;中左右&#xff09;&#xff0c;也可以使用后序遍历&#xff08;左右中&#xff09;&#xff0c;…

第三方软件测试公司分享:软件渗透测试的测试内容和注意事项

软件渗透测试是一种通过模拟攻击的方式来评估软件系统的安全性和漏洞&#xff0c;以发现并修复系统中的安全弱点。保护用户的数据和信息不被恶意攻击者利用&#xff0c;也是软件产品开发流程中重要的环节&#xff0c;可以帮助开发团队完善产品质量&#xff0c;提高用户满意度。…

【Unity】RPG2D龙城纷争(六)关卡编辑器之角色编辑

更新日期&#xff1a;2024年6月26日。 项目源码&#xff1a;第五章发布&#xff08;正式开始游戏逻辑的章节&#xff09; 索引 简介一、角色编辑模式1.将字段限制为只读2.创建角色&#xff08;刷角色&#xff09;3.预览所有角色4.编辑选中角色属性5.移动角色位置6.移除角色 简介…

应用决策树批量化自动生成【效果好】【非过拟合】的策略集

决策树在很多公司都实际运用于风险控制,之前阐述了决策树-ID3算法和C4.5算法、CART决策树原理(分类树与回归树)、Python中应用决策树算法预测客户等级和Python中调用sklearn决策树。 本文介绍应用决策树批量自动生成效果好,非过拟合的策略集。 文章目录 一、什么是决策树二…