手写spring

参考视频

https://www.bilibili.com/video/BV1tR4y1F75R?p=1

目录

在这里插入图片描述

手写spring

在这里插入图片描述
Test

package com.zs.service;

import com.zs.spring.ZsApplicationContext;

public class Test {
    public static void main(String[] args) {
        //1. 需要有spring容器
        ZsApplicationContext zsApplicationContext = new ZsApplicationContext(AppConfig.class);
        UserService userService = (UserService) zsApplicationContext.getBean("userService");
    }
}

UserService

package com.zs.service;


import com.zs.spring.Component;

@Component("userService")
public class UserService {

}

ZsApplicationContext

package com.zs.spring;

public class ZsApplicationContext {
    private Class configClass;

    public ZsApplicationContext(Class configClass) {
        this.configClass = configClass;
    }

    public Object getBean(String beanName) {
        return null;
    }
}

Component

package com.zs.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.TYPE) //只能写在类上面
public @interface Component {
    String value() default "";
}

ComponentScan

package com.zs.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.TYPE) //只能写在类上面
public @interface ComponentScan {
    String value() default "";
}

AppConfig

package com.zs.service;


import com.zs.spring.ComponentScan;

@ComponentScan("com.zs.service")
public class AppConfig {
}

模拟扫描

package com.zs.spring;

import com.sun.media.sound.SoftTuning;

import java.io.File;
import java.net.URL;

public class ZsApplicationContext {
    private Class configClass;

    public ZsApplicationContext(Class configClass) {
        this.configClass = configClass;

        //模拟扫描
        if (configClass.isAnnotationPresent(ComponentScan.class)){
            ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
            String path = componentScanAnnotation.value();//扫描路径 com.zs.service

            path = path.replace(".","/"); // com/zs/service

            //使用类加载器获取相对路径
            ClassLoader classLoader = ZsApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file = new File(resource.getFile());

//            System.out.println(file);

            if (file.isDirectory()){
                File[] files = file.listFiles();
                for (File f : files) {
                    String fileName = f.getAbsolutePath();
//                    System.out.println(fileName);
                    if (fileName.endsWith(".class")){
                        try {
                            String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                            className = className.replace("/",".");

                            System.out.println(className);

                            Class<?> clazz = classLoader.loadClass(className);

                            if (clazz.isAnnotationPresent(Component.class)){
                                //bean
                                
                                
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }

                    }
                }
            }


        }
    }

    public Object getBean(String beanName) {
        return null;
    }
}

模拟BeanDefinition

Scope

package com.zs.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.TYPE) //只能写在类上面
public @interface Scope {
    String value() default "";
}

在这里插入图片描述
BeanDefinition

package com.zs.spring;

public class BeanDefinition {
    private Class type;
    private String scope;

    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;
    }
}

ZsApplicationContext

package com.zs.spring;

import com.sun.media.sound.SoftTuning;

import java.io.File;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;

public class ZsApplicationContext {
    private Class configClass;

    private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();

    public ZsApplicationContext(Class configClass) {
        this.configClass = configClass;

        //模拟扫描
        if (configClass.isAnnotationPresent(ComponentScan.class)){
            ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
            String path = componentScanAnnotation.value();//扫描路径 com.zs.service

            path = path.replace(".","/"); // com/zs/service

            //使用类加载器获取相对路径
            ClassLoader classLoader = ZsApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file = new File(resource.getFile());

//            System.out.println(file);

            if (file.isDirectory()){
                File[] files = file.listFiles();
                for (File f : files) {
                    String fileName = f.getAbsolutePath();
//                    System.out.println(fileName);
                    if (fileName.endsWith(".class")){



                        try {
                            String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                            className = className.replace("/",".");

                            System.out.println(className);

                            Class<?> clazz = classLoader.loadClass(className);



                            if (clazz.isAnnotationPresent(Component.class)){
                                //BeanDefinition

                                Component component = clazz.getAnnotation(Component.class);
                                String beanName = component.value();

                                BeanDefinition beanDefinition = new BeanDefinition();
                                beanDefinition.setType(clazz);

                                if (clazz.isAnnotationPresent(Scope.class)){
                                    Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                    beanDefinition.setScope(scopeAnnotation.value());
                                }else{
                                    beanDefinition.setScope("singleton");
                                }

                                //将扫描出得bean定义对象放入集合中
                                beanDefinitionMap.put(beanName,beanDefinition);
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }



                    }
                }
            }


        }
    }

    public Object getBean(String beanName) {
        return null;
    }
}

模拟getBean

package com.zs.spring;

import com.sun.media.sound.SoftTuning;

import java.io.File;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;

public class ZsApplicationContext {
    private Class configClass;

    //bean定义池
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    //单例池
    private ConcurrentHashMap<String, Object> singletonObjects = new ConcurrentHashMap<>();

    public ZsApplicationContext(Class configClass) {
        this.configClass = configClass;

        //模拟扫描
        if (configClass.isAnnotationPresent(ComponentScan.class)) {
            ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);
            String path = componentScanAnnotation.value();//扫描路径 com.zs.service

            path = path.replace(".", "/"); // com/zs/service

            //使用类加载器获取相对路径
            ClassLoader classLoader = ZsApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(path);
            File file = new File(resource.getFile());

//            System.out.println(file);

            if (file.isDirectory()) {
                File[] files = file.listFiles();
                for (File f : files) {
                    String fileName = f.getAbsolutePath();
//                    System.out.println(fileName);
                    if (fileName.endsWith(".class")) {


                        try {
                            String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                            className = className.replace("/", ".");

                            System.out.println(className);

                            Class<?> clazz = classLoader.loadClass(className);


                            if (clazz.isAnnotationPresent(Component.class)) {
                                //BeanDefinition

                                Component component = clazz.getAnnotation(Component.class);
                                String beanName = component.value();

                                BeanDefinition beanDefinition = new BeanDefinition();
                                beanDefinition.setType(clazz);

                                if (clazz.isAnnotationPresent(Scope.class)) {
                                    Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                    beanDefinition.setScope(scopeAnnotation.value());
                                } else {
                                    beanDefinition.setScope("singleton");
                                }

                                //将扫描出得bean定义对象放入集合中
                                beanDefinitionMap.put(beanName, beanDefinition);
                            }
                        } catch (ClassNotFoundException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }

        //遍历出单例bean
        for (String beanName : beanDefinitionMap.keySet()) {
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            if (beanDefinition.getScope().equals("singleton")){
                //将单例bean放入到单例池中
                Object bean =  createBean(beanName,beanDefinition);
                singletonObjects.put(beanName,bean);
            }
        }
    }
    private Object createBean(String beanName,BeanDefinition beanDefinition){

        //bean 创建
        return null;
    }


    public Object getBean(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition == null) {
            throw new NullPointerException();
        } else {
            String scope = beanDefinition.getScope();
            if (scope.equals("singleton")){
                //单例
                Object bean = singletonObjects.get(beanName);
                if (bean == null){
                    Object o = createBean(beanName,beanDefinition);
                    singletonObjects.put(beanName,0);
                }
                return bean;
            }else{
                //多例
                return createBean(beanName,beanDefinition);
            }
        }
    }
}

createBean方法实现

    private Object createBean(String beanName,BeanDefinition beanDefinition){

        //bean 创建
        Class clazz = beanDefinition.getType();
        try {
            Object instance = clazz.getConstructor().newInstance();
            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

测试单例,多例

package com.zs.service;

import com.zs.spring.ZsApplicationContext;

public class Test {
    public static void main(String[] args) {
        //1. 需要有spring容器
        ZsApplicationContext zsApplicationContext = new ZsApplicationContext(AppConfig.class);
//        UserService userService = (UserService) zsApplicationContext.getBean("userService");
        System.out.println(zsApplicationContext.getBean("userService"));
        System.out.println(zsApplicationContext.getBean("userService"));
        System.out.println(zsApplicationContext.getBean("userService"));
    }
}

模拟依赖注入

扫描时如果没有给名称默认给类名

  //如果没有自定义bean名称,取类名第一字母小写
  if (beanName.equals("")){
      beanName = Introspector.decapitalize(clazz.getSimpleName());
  }

OrderService

package com.zs.service;


import com.zs.spring.Component;
import com.zs.spring.Scope;

@Component
public class OrderService {

}

测试

package com.zs.service;

import com.zs.spring.ZsApplicationContext;

public class Test {
    public static void main(String[] args) {
        //1. 需要有spring容器
        ZsApplicationContext zsApplicationContext = new ZsApplicationContext(AppConfig.class);
//        UserService userService = (UserService) zsApplicationContext.getBean("userService");
        System.out.println(zsApplicationContext.getBean("userService"));
        System.out.println(zsApplicationContext.getBean("userService"));
        System.out.println(zsApplicationContext.getBean("userService"));
        System.out.println(zsApplicationContext.getBean("orderService"));
    }
}

package com.zs.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 {

}

UserService


package com.zs.service;


import com.zs.spring.Autowired;
import com.zs.spring.Component;
import com.zs.spring.Scope;

@Component("userService")
public class UserService {

    @Autowired
    private OrderService orderService;

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

测试,获取为null

package com.zs.service;

import com.zs.spring.ZsApplicationContext;

public class Test {
    public static void main(String[] args) {
        //1. 需要有spring容器
        ZsApplicationContext zsApplicationContext = new ZsApplicationContext(AppConfig.class);
        UserService userService = (UserService) zsApplicationContext.getBean("userService");
        userService.test();
    }
}

依赖注入简单版实现

private Object createBean(String beanName,BeanDefinition beanDefinition){

        //bean 创建
        Class clazz = beanDefinition.getType();
        try {
            Object instance = clazz.getConstructor().newInstance();


            //简单版依赖注入
            //获取所有属性,给有注解的属性添加值
            for (Field f : clazz.getDeclaredFields()) {
                if (f.isAnnotationPresent(Autowired.class)){
                    f.setAccessible(true);
                    f.set(instance,getBean(f.getName()));
                }
            }


            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

Aware回调

依赖注入以后判断是否 实现了 BeanNameAware接口,实现回调

private Object createBean(String beanName,BeanDefinition beanDefinition){

        //bean 创建
        Class clazz = beanDefinition.getType();
        try {
            Object instance = clazz.getConstructor().newInstance();


            //简单版依赖注入
            //获取所有属性,给有注解的属性添加值
            for (Field f : clazz.getDeclaredFields()) {
                if (f.isAnnotationPresent(Autowired.class)){
                    f.setAccessible(true);
                    f.set(instance,getBean(f.getName()));
                }
            }

            //依赖注入以后判断是否 实现了 BeanNameAware接口,实现回调
            if (instance instanceof BeanNameAware){
                ((BeanNameAware)instance).setBeanName(beanName);
            }


            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }
package com.zs.spring;

public interface BeanNameAware {
    void setBeanName(String beanName);
}

测试

package com.zs.service;


import com.zs.spring.Autowired;
import com.zs.spring.Component;
import com.zs.spring.Scope;

@Component("userService")
public class UserService {

    @Autowired
    private OrderService orderService;

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

package com.zs.service;


import com.zs.spring.BeanNameAware;
import com.zs.spring.Component;
import com.zs.spring.Scope;

@Component
public class OrderService implements BeanNameAware {

    private String beanName;

    public String getBeanName() {
        return beanName;
    }

    @Override
    public void setBeanName(String beanName) {
        this.beanName = beanName;
    }
}

初始化回调

    private Object createBean(String beanName,BeanDefinition beanDefinition){

        //bean 创建
        Class clazz = beanDefinition.getType();
        try {
            Object instance = clazz.getConstructor().newInstance();


            //简单版依赖注入
            //获取所有属性,给有注解的属性添加值
            for (Field f : clazz.getDeclaredFields()) {
                if (f.isAnnotationPresent(Autowired.class)){
                    f.setAccessible(true);
                    f.set(instance,getBean(f.getName()));
                }
            }

            //依赖注入以后判断是否 实现了 BeanNameAware接口,实现回调
            if (instance instanceof BeanNameAware){
                ((BeanNameAware)instance).setBeanName(beanName);
            }

            //初始化
            if (instance instanceof InitializingBean){
                ((InitializingBean)instance).afterPropertiesSet();
            }

            return instance;
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return null;
    }

模拟BeanPostProcessor

package com.zs.spring;

public interface BeanPostProcessor {
    void postProcessBeforeInitialization(String beanName,Object bean);
    void postProcessAfterInitialization(String beanName,Object bean);
}

    private ArrayList<BeanPostProcessor> beanPostProcessorsList = new ArrayList<>();



构造方法中
    if (clazz.isAnnotationPresent(Component.class)) {
        //该类上是否实现BeanPostProcessor接口
        if (BeanPostProcessor.class.isAssignableFrom(clazz)){
            BeanPostProcessor instance = (BeanPostProcessor) clazz.newInstance();
            beanPostProcessorsList.add(instance);
        }




createBean方法中
    for (BeanPostProcessor beanPostProcessor : beanPostProcessorsList) {
        beanPostProcessor.postProcessBeforeInitialization(beanName,instance);
    }

    //初始化
    if (instance instanceof InitializingBean){
        ((InitializingBean)instance).afterPropertiesSet();
    }

    for (BeanPostProcessor beanPostProcessor : beanPostProcessorsList) {
        beanPostProcessor.postProcessAfterInitialization(beanName,instance);
    }

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Spring Framework是一个开源的Java平台,它提供了一组全面的工具来支持Java应用程序开发。它主要包括IoC容器、AOP框架、事务管理、MVC框架、DAO框架、连接池等。它可以帮助程序员更好地组织代码,减少重复性工作,提高代码质量。手写Spring框架需要对Java编程和设计模式有较深的了解,并对Spring框架的源码有着深入的研究。 ### 回答2: Spring框架是一个开源的Java平台,用于构建企业级应用程序。它提供了一种全面的编程和配置模型,用于开发基于Java的应用程序和服务。手写Spring框架意味着从头开始实现Spring的核心功能。 手写Spring框架的基本步骤包括: 1. 创建一个核心容器类,用于管理应用程序中的Bean对象。这个容器类需要提供注册、获取和销毁Bean的功能。 2. 定义一个Bean注解,用于标识哪些类应该被容器所管理。 3. 创建一个Bean定义类,用于存储每个Bean的元数据信息,包括类名、作用域和依赖关系等。 4. 实现依赖注入功能,通过读取Bean定义中的依赖关系,将相关的Bean对象注入到目标Bean中。 5. 提供AOP(面向切面编程)功能,允许开发者在应用程序的特定点进行横切关注点的处理。 6. 实现声明式事务管理功能,使用注解或XML配置方式来处理数据库事务。 7. 提供对不同数据访问技术(如JDBC、ORM框架、NoSQL等)的支持,通过集成相应的库来简化数据访问代码。 8. 增加对Web开发的支持,如处理请求、渲染视图等。 手写Spring框架需要具备对Java语言的深入了解,熟悉反射、代理、设计模式等概念和技术。还需要对依赖注入、AOP、事务管理、Web开发等方面有一定的理解。实现一个完整的Spring框架是一个庞大而复杂的任务,需要经过反复的设计、开发和测试。通过手写Spring框架,可以更深入地理解Spring的原理和内部机制,提高对框架的使用和调试能力。 ### 回答3: 手写Spring框架是一个相当复杂的任务,但我可以简要介绍手写Spring框架的一些关键步骤和组成部分。 1. 依赖注入:Spring框架的核心概念之一是依赖注入。我们需要编写一个容器,负责管理和维护各个对象之间的依赖关系。可以使用反射机制来实现依赖注入。 2. 控制反转:Spring框架通过控制反转(IoC)来管理对象的创建和生命周期。我们需要编写一个BeanFactory,负责加载和实例化对象,并将依赖注入到相应的对象中。 3. 配置文件:手写Spring框架也需要一个配置文件,用于定义对象的依赖关系和属性。我们可以使用XML、注解或者JavaConfig等方式来定义配置文件。 4. AOP支持:Spring框架提供了面向切面编程(AOP)的支持,可以通过编写切面和通知来实现横切关注点的统一处理。我们需要实现一个AOP框架,用于拦截和处理切面逻辑。 5. MVC模式:Spring框架也提供了一个MVC框架,用于处理Web应用程序的请求和响应。我们需要编写一个DispatcherServlet,负责将请求分发给相应的控制器,并处理模型和视图的交互。 6. 整合其他技术:Spring框架还可以与其他技术进行整合,例如数据库访问、事务管理、安全性控制等。我们需要编写相应的模块,将这些技术与Spring框架集成起来。 虽然这只是一个简要的介绍,手写Spring框架是一个非常庞大的工程,需要深入理解Spring的原理和设计思想,并具备扎实的Java编程能力。但通过手写Spring框架,我们可以更好地掌握Spring的核心概念和原理,并加深对框架的理解。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

悠闲的线程池

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值