手写spring框架

在这里插入图片描述

手写spring框架 (包含依赖注入,单例多例部分实现,spring常用注解用自定义注解实现)


代码文件结构

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、实例代码

package com.spring.SpringHandWriting;

import lombok.Data;

@Data
public class BeanDefinition {
    private Class type;
    private String scope ;
    private Boolean isLazy ;
}

package com.spring.SpringHandWriting;

@MyComponentScan("com.spring.SpringHandWriting")
public class MyAppConfig {

}

```java
 
package com.spring.SpringHandWriting;

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 MyComponent {
    String value() default "";
}

package com.spring.SpringHandWriting;

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 MyComponentScan {
    String value() default "";
}

package com.spring.SpringHandWriting;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

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.HashMap;
import java.util.Map;

public class MySpringContext {
    private Class configClass;
    private Map<String, BeanDefinition> beanDefinitionMap = new HashMap<>();
    private Map<String, Object> singletonObjects = new HashMap<>();

    public MySpringContext(Class<?> myAppConfigClass) {
        this.configClass = myAppConfigClass;
        //扫描 主要是扫描哪些对象被定义bean 加载配置信息到beanDefinitionMap
        this.scan(configClass);
        System.out.println(this.beanDefinitionMap);
        //如果是单例模式 则创建对象 加入单例池
       for( Map.Entry<String, BeanDefinition> key :beanDefinitionMap.entrySet()){
            String beanName  = key.getKey();
           BeanDefinition beanDefinition = key.getValue();
           if("singleton".equals(beanDefinition.getScope())){
               Object bean = createBean(beanName, beanDefinition);
               singletonObjects.put(beanName, bean);
           }

       }
    }

    private Object createBean(String beanName, BeanDefinition beanDefinition) {
       Object instance = null;
       Class clazz = beanDefinition.getType();
        try {
            instance = clazz.getConstructor().newInstance();

            //依赖注入
            for( Field field :clazz.getDeclaredFields()){
                if(field.isAnnotationPresent(Autowired.class)){
                    //判断是否有成员变量有Autowired注解 如果有就生成bean注入
                    field.setAccessible(true);
                    field.set(instance,getBean(field.getName()));
                }
            }

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


    private void scan(Class configClass) {
        System.out.println(configClass);
        MyComponentScan myComponentScan = (MyComponentScan) configClass.getAnnotation(MyComponentScan.class);
        String path = myComponentScan.value().replace(".", "/");
        ClassLoader classLoader = configClass.getClassLoader();
        URL resource = classLoader.getResource(path);
        File file = new File(resource.getFile());
        if (file.isDirectory()) {
            for (File f : file.listFiles()) {
                String absolutePath = f.getPath();
                absolutePath = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"));
                absolutePath = absolutePath.replace("\\", ".");

                try {
                    Class clazz = classLoader.loadClass(absolutePath);
                    BeanDefinition beanDefinition = new BeanDefinition();
                    beanDefinition.setType(clazz);
                    String beanName = "";
                    //如果有component注解 说明是bean加入map
                    if(clazz.isAnnotationPresent(MyComponent.class)){
                         beanName = Introspector.decapitalize(clazz.getSimpleName());
                        System.out.println(beanName);

                        //判断scope 注解 如果是为空就默认是单例
                        if(clazz.isAnnotationPresent(Scope.class)){
                            Scope scopeAnnotation = (Scope) clazz.getAnnotation(Scope.class);
                            String value = scopeAnnotation.value();

                            if(StringUtils.isBlank(value)){
                                value = "singleton";
                            }
                            beanDefinition.setScope(value);

                        }


                        beanDefinitionMap.put(beanName, beanDefinition);


                    }


                } catch (ClassNotFoundException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public Object getBean(String beanName) {
        //如果beanDefinitionMap 说明没有当前的bean配置
        if (!beanDefinitionMap.containsKey(beanName)) {
            throw new NullPointerException();
        }

        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        //spring默认是单例bean
        if ("singleton".equals(beanDefinition.getScope())||beanDefinition.getScope()==null) {
            Object singletonBean = singletonObjects.get(beanName);
            if (singletonBean == null) {
                singletonBean = createBean(beanName, beanDefinition);
                singletonObjects.put(beanName, singletonBean);
            }
            return singletonBean;
        } else {
            // 原型
            Object prototypeBean = createBean(beanName, beanDefinition);
            return prototypeBean;
        }
    }

}

package com.spring.SpringHandWriting;

import org.springframework.stereotype.Component;

@MyComponent("orderService")
public class OrderService {

}

package com.spring.SpringHandWriting;

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

package com.spring.SpringHandWriting;

public class SptingMain {
    public static void main(String[] args) {
        MySpringContext mySpringContext = new MySpringContext(MyAppConfig.class);
         UserService o = (UserService) mySpringContext.getBean("userService");
         System.out.println(o);
         System.out.println(o.getOrderService());//依赖注入对象
    }
}

package com.spring.SpringHandWriting;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;

@Data
@Scope("singleton")
@MyComponent("userService")
public class UserService {
    @Autowired
    private OrderService orderService;
}

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值