spring之HelloWord版

server/2024/10/20 5:45:51/

目录

基础结构说明

涉及到的功能

执行流程

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/server/53239.html

相关文章

IIC学习笔记(立创STMF4开发板)

目录 #I2C涉及相关知识 #I2C相关介绍 欢迎指正&#xff0c;希望对你&#xff0c;有所帮助&#xff01;&#xff01;&#xff01; 个人学习笔记&#xff0c;参考文献&#xff0c;链接最后&#xff01;&#xff01;&#xff01; #I2C涉及相关知识 SDA串行数据线&#xff1a; Ser…

Interview preparation--elasticSearch正排索引原理

正排索引 ElastciSearch 适合做或者说擅长做全文检索&#xff0c;在做全文检索的时候&#xff0c;他会通过生成倒排索引的方式来辅助查询&#xff0c;生成一个词项到 文档id的一个倒排表&#xff0c;这样直接通过 词项可以快速找到所有的 稳定信息。 但是并不是所有的搜索都是…

淘客返利系统的分布式事务处理

淘客返利系统的分布式事务处理 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨如何在淘客返利系统中实现分布式事务处理&#xff0c;确保系统的数…

通过代理从ARDUINO IDE直接下载开发板包

使用免费代理 实现ARDUINO IDE2.3.2 下载ESP8266/ESP32包 免费代理 列表 测试代理是否可用的 网站 有时&#xff0c;代理是可用的&#xff0c;但依然有可能找不到开发板管理器的资料包。 可以多换几个代理试试。 代理的配置 文件 -> 首选项 -> 网络 进入后做如下配置…

基于weixin小程序农场驿站系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;农场资讯管理&#xff0c;用户管理&#xff0c;卖家管理&#xff0c;用户分享管理&#xff0c;分享类型管理&#xff0c;商品信息管理&#xff0c;商品类型管理 开发系统&#xff1a;Windows 架构模式&…

WPF----自定义滚动条ScrollViewer

滚动条是项目当中经常用到的一个控件&#xff0c;大部分对外项目都有外观的需求&#xff0c;因此需要自定义&#xff0c;文中主要是针对一段动态的状态数据进行展示&#xff0c;并保证数据始终在最新一条&#xff0c;就是需要滚动条滚动到底部。 1&#xff0c;xaml中引入 <…

微信小程序自定义指令

微信小程序自定义指令 在微信小程序开发中&#xff0c;自定义指令&#xff08;Custom Directive&#xff09;是一种强大的工具&#xff0c;它允许开发者在页面的模板中编写复用性高、逻辑清晰的代码片段&#xff0c;用于处理视图层的逻辑和交互。通过自定义指令&#xff0c;开发…

决策树之美:探索机器学习中的多面手

在机器学习领域&#xff0c;决策树算法以其独特的优势在众多算法中脱颖而出。作为一种监督学习算法&#xff0c;决策树通过递归地将数据集分割成越来越小的子集&#xff0c;直到满足某个停止准则&#xff0c;从而构建起一个树形结构的模型。本文将深入探讨决策树算法的主要优点…