300行代码实现简易Spring框架

源码地址

该简易Spring框架实现的功能有

  1. 容器启动
  2. 包扫描
  3. 单例、多例Bean
  4. Bean的创建
  5. 依赖注入
  6. Aware回调函数
  7. 初始化
  8. 后处理器
  9. AOP

目录结构如下,service包为模拟业务逻辑,spring包为spring的实现(核心),其中ApplicationContext为核心类。

在这里插入图片描述

package com.ego.spring;

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.List;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 袁梦达
 */
public class ApplicationContext {


    //配置文件  扫描包
    private Class configClass;
    //bean工厂
    private ConcurrentHashMap<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>();
    //单例bean
    private ConcurrentHashMap<String, Object> singletonMap = new ConcurrentHashMap<>();
    //后处理器
    private List<BeanPostProcessor> beanPostProcessorList = new ArrayList<>();

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

        //扫描
        if(configClass.isAnnotationPresent(ComponentScan.class)){

            //获取ComponentScan的值
            ComponentScan componentScanAnnotation = (ComponentScan) configClass.getAnnotation(ComponentScan.class);

            //com.ego.service
            String scanPath = componentScanAnnotation.value();
            //com/ego/service
            scanPath = scanPath.replace(".", "/");
            //去out文件夹里找到扫描的包
            ClassLoader classLoader = ApplicationContext.class.getClassLoader();
            URL resource = classLoader.getResource(scanPath);

            //扫描包里每一个class文件是否为Bean
            File file = new File(resource.getFile());
            if(file.isDirectory()){
                for (File f : file.listFiles()) {
                    String fileName = f.getAbsolutePath();
                    if(fileName.endsWith(".class")){
                        String className = fileName.substring(fileName.indexOf("com"), fileName.indexOf(".class"));
                        className = className.replace("\\", ".");

                        try {

                            Class<?> clazz = classLoader.loadClass(className);
                            //判断是否为Bean
                            if(clazz.isAnnotationPresent(Component.class)){

                                //如果是后处理器则加入list中
                                if(BeanPostProcessor.class.isAssignableFrom(clazz)){
                                    BeanPostProcessor instance = (BeanPostProcessor) clazz.getConstructor().newInstance();
                                    beanPostProcessorList.add(instance);
                                }

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

                                //默认Bean的name
                                if("".equals(beanName)){
                                    beanName = Introspector.decapitalize(clazz.getSimpleName());
                                }

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

                                //作用域
                                if(clazz.isAnnotationPresent(Scope.class)){
                                    Scope scopeAnnotation = clazz.getAnnotation(Scope.class);
                                    beanDefinition.setScope(scopeAnnotation.value());
                                }else{
                                    beanDefinition.setScope("singleton");
                                }
                                beanDefinitionMap.put(beanName, beanDefinition);
                            }

                        } catch (ClassNotFoundException | InvocationTargetException | InstantiationException |
                                 IllegalAccessException | NoSuchMethodException e) {
                            throw new RuntimeException(e);
                        }
                    }
                }

            }
        }

        //将所有单例Bean加入到单例池
        for (String beanName : beanDefinitionMap.keySet()) {
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            if("singleton".equals(beanDefinition.getScope())){
                Object bean = createBean(beanName, beanDefinition);
                singletonMap.put(beanName, bean);
            }
        }


    }

    private Object createBean(String beanName, BeanDefinition beanDefinition){
        Class clazz = beanDefinition.getClazz();
        Object bean = null;
        try {
            //实例化
            bean = clazz.getConstructor().newInstance();

            //依赖注入
            for (Field field : clazz.getFields()) {
                if(field.isAnnotationPresent(Autowired.class)){
                    field.setAccessible(true);
                    field.set(bean, getBean(field.getName()));
                }
            }

            //执行回调接口
            if(bean instanceof BeanNameAware){
                ((BeanNameAware)bean).setBeanName(beanName);
            }

            //前置处理器
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                bean = beanPostProcessor.postProcessorBeforeInitialization(beanName, bean);
            }

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

            //后置处理器
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                bean = beanPostProcessor.postProcessorAfterInitialization(beanName, bean);
            }

        } catch (InstantiationException | InvocationTargetException | IllegalAccessException | NoSuchMethodException e) {
            throw new RuntimeException(e);
        }
        return bean;
    }
    public Object getBean(String beanName){
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);

        if(beanDefinition == null){
            throw new NullPointerException("bean不存在");
        }else {
            String scope = beanDefinition.getScope();
            if("singleton".equals(scope)){
                //单例Bean直接从单例池中获取
                Object bean = singletonMap.get(beanName);

                //此条件发生在初始化容器时,生成单例Bean的时候
                //在某个Bean依赖注入时,如果被注入的单例Bean还没有实例化,
                //那么就要先实例化被注入的单例Bean,再实例化当前Bean
                if(bean == null){
                    bean= createBean(beanName, beanDefinition);
                }
                return bean;
            }else{
                return createBean(beanName, beanDefinition);
            }
        }
    }
}

package com.ego.spring;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 袁梦达
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Autowired {

}

package com.ego.spring;

/**
 * @author 袁梦达
 */
public class BeanDefinition {
    private Class clazz;
    private String scope;

    public Class getClazz() {
        return clazz;
    }

    public void setClazz(Class clazz) {
        this.clazz = clazz;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }
}

package com.ego.spring;

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

package com.ego.spring;

public interface BeanPostProcessor {
    Object postProcessorBeforeInitialization(String beanName, Object bean);
    Object postProcessorAfterInitialization(String beanName, Object bean);
}

package com.ego.spring;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 袁梦达
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
    String value() default "";
}

package com.ego.spring;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 袁梦达
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
    String value() default "";
}

package com.ego.spring;

/**
 * @author 袁梦达
 */
public interface InitializingBean {
    void afterPropertiesSet();
}

package com.ego.spring;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * @author 袁梦达
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
    String value() default "";
}

package com.ego.service;

import com.ego.spring.BeanPostProcessor;
import com.ego.spring.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessorBeforeInitialization(String beanName, Object bean) {
        if(beanName.equals("userService")){
            System.out.println("postProcessorBeforeInitialization...");
        }
        return bean;
    }

    @Override
    public Object postProcessorAfterInitialization(String beanName, Object bean) {
        if(beanName.equals("userService")){
            System.out.println("postProcessorAfterInitialization...");
            return Proxy.newProxyInstance(MyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    System.out.println("aop执行...");
                    return method.invoke(bean, args);
                }
            });
        }
        return bean;
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值