Spring——Bean的创建生命周期以及手动模拟Spring。

Spring介绍

Spring 框架是一个Java平台,它为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此您可以专注于应用程序的开发。

Spring可以让您从“plain old Java objects”(POJO)中构建应用程序和通过非侵入性的POJO实现企业应用服务。此功能适用于Java SE的编程模型,全部的或部分的适应Java EE模型。

以上摘自Spring官网中文版本。

spring5框架图

在这里插入图片描述
图片来自Spring官网。

SpringBean的创建生命周期

我们都知道Spring的三大特点 : IOC(控制反转), DI(依赖注入)以及AOP(切面)。

控制反转: 在传统的 java SE设计模式中,需要创建一个对象,全部是依靠程序猿手动 new() 一个对象,进行应用。而spring 中则是使用容器的方式,将一个对象交给容器,容器帮你创建,初始化以及销毁。
比如说:
       以前,我们创建一个Controller类,调用一个Service 类,是直接在Controller 中new一个Service,然后调用对应的方法。
       现在,我们把需要创建的对象交给Spring 管理。只要能要spring 扫描到对应的类,spring的容器会帮你将对象进行创建,属性注入,初始化。将创建对象,创建什么对象的权利交给Spring容器。这就是控制反转。

依赖注入: 就是spring 在帮你创建对象后,判断对象中有哪些属性是需要spring帮你初始化的(@Atowried,@Resouce等),根据属性的类型,名称从容器中获取对象。

AOP: 这个都知道,就是在执行一个方法前或者后,先执行的一个方法。比如说 日志记录,事物管理器这些的。

BEAN的创建过程

下面说的bean的创建过程只是简单的概述下,spring源码中的肯定不会是这么简单的。

  1. 首先创建一个对象,我们都知道是要调用对象的构造方法,而我们的spring就需要根据对象的配置推断出构造方法来。
  2. 根据推断的构造方法,创建对象。
  3. 得到这个对象后依赖注入,反射的方式。
  4. 判断对象是否实现了BeanNameAware,ApplicationContextAware等接口,调用对应的回调方法并传入对应的参数。
    例如:
@Component
public class SpringUtil implements ApplicationContextAware{

	private static ApplicationContext ctx;
	
	void setApplicationContext(ApplicationContext applicationContext){
		ctx= applicationContext;
	}
}

这个类对象创建后,就会回调setApplicationContext这个方法,前提是这个类交给了spring管理。

  1. Aware回调后,Spring会判断该对象中是否存在某个方法被@PostConstruct注解了,如果存在,Spring会调用当前对象的此方法(初始化前)
  2. 判断类是否实现了InitializingBean方法,如果实现了,代表该类实现了afterPropertiesSet方法,调用这个方法。
  3. 最后,Spring会判断当前对象需不需要进行AOP,如果不需要那么Bean就创建完了,如果需要进行AOP,实现BeanPostPorcessor 类。则会进行动态代理并生成一个代理对象做为Bean(初始化后)

大概流程图
在这里插入图片描述

简单模拟Spring创建bean

  1. 首先,创建一个空白的MAVEN项目,叫MySpringModel,在java目录下建立两个包,com.project.spring(放模拟spring的代码),com.project.service(自己的业务代码)。
    如下图:
    在这里插入图片描述

  2. 我们都知道,现在Spring都流行使用注解的方式,而不是xml的方式,所以我们模拟的时候使用的是注解的方式。创建相关的注解, @ComponentScan(扫描包路径的注解),@Component(将对象交给spring管理的注解),@Scope(作用域) ,@PostConstrust,以及依赖注入的 @Autowired

@ComponentScan:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {
    String value() default "";
}

@Component

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component{
    String value() default "";
}

@Scope

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Scope {
    String value() default "";
}

@PostConstrust

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PostConstruct {
}

@Autowired

@Target({ElementType.METHOD,ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
  1. 实现一个配置类.MyConfig.java
@ComponentScan("com.project.service") //扫描的包路径
public class MyConfig {
}
  1. 创建一个类信息的存储器 BeanDefinition,用来存储类的信息。
public class BeanDefinition {
    /*
     * 单列 还是多例
     **/
    private String scope;

    private Class clazz;

    public String getScope() {
        return scope;
    }

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

    public Class getClazz() {
        return clazz;
    }

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

  1. 创建一个初始化的接口InitalitionBean
public interface InitalitionBean {

    void afterPropertiesSet();

}
  1. 创建一个后置处理器的接口BeanPostProcess,当bean创建完成后,会调用他的afterBeanPostProcess方法。
public interface BeanPostProcess {

    default Object afterBeanPostProcess(String beanName, Object bean) {
        return bean;
    }
    default Object beforeBeanPostProcess(String beanName, Object bean) {
        return bean;
    }
}

  1. 好了现在需要用的的注解和类都已经创建了,那么我们还需要一个启动容器。在spring包下面创建一个启动类MyApplicationContext 。首先我们分析下,一个启动类至少需要什么。
    a. 我的启动类的构造方法是不是也应该像Spring一样能传入一个MyConfig的配置类。

    b. 我的启动类是不是要能够从MyConfig配置类中获取@ComponentScan注解中获取扫描包的路径。

    c. 我扫描的时候我是不是要把扫描到的类信息,封装起来,保存下来,如果我下次使用的时候,能直接使用我保存的信息。这里要创建一个BeanDefinition类用来存储(源码中也是用的BeanDefinition)。但是我扫描的类有多个是不是要用一个集合存储起来,所以要在启动类中添加一个map,所以在启动类中添加一个属性Map ,叫BeanDefinitionMap 。(源码中也是这个)

    d.我扫描的时候,我这个类可能要执行初始化话后的方法,我要判断是否实现了BeanPostProcessor ,注意实现了BeanPostProcessor的类后,所有bean初始化后的阶段都要去调用实现了BeanPostProcessor的afterBeanPostProcess方法。 我们是不是要有个集合将所有实现了BeanPostProcessor的类存这个 所以我们要添加一个 beanPostProcessList 。

    e. 我获取了需要加载到类信息,我是不是要将它加载到JVM中去,调用classLoader方法.

    f.我是不是需要一个创建bean的方法。并且将我创建的bean 存到容器中,所以我的容器还需要一个字段存放我创建Bean,那么创建一个Map,叫singleObject(单例池)。

    j. 最后我是不是要提供一个getBean方法,让我能去使用我创建的bean.

  2. 现在让我们按照上面的分析,来逐步实现。
    a. 实现一个构造方法 ,并且

public class MySpringApplicationContext{
	public MySpringApplicationContext(Class clazz) {//这里就是传入自定义的配置类。
        //扫描
        try {
            scan(clazz);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
}

b. 根据配置类扫描包

public class MySpringApplicationContext{
	public MySpringApplicationContext(Class clazz) {//这里就是传入自定义的配置类。
        //扫描
        try {
            scan(clazz);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    //扫描方法
	private void scan(Class clazz) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取扫描路径
        if (!clazz.isAnnotationPresent(ComponentScan.class)) {
            throw new RuntimeException("未找到扫描路径");
        }
        //获取扫描路径
        ComponentScan componentScanAnnotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);//获取配置类上的 ComponentScan
        String scanPath = componentScanAnnotation.value(); //获取路径
        //获取路径下所有的class文件
        List<Class> classeList = getBeanClass(scanPath);
        

    }
    //根据路径获取class文件
    private List<Class> getBeanClass(String scanPath) throws ClassNotFoundException {
        List<Class> classeList = new ArrayList<>();
        scanPath = scanPath.replace(".", "/");
        URL resource = ClassLoader.getSystemResource(scanPath);
        File dir = new File(resource.getFile());
        //获取启动类的加载器
        ClassLoader classLoader = MySpringApplicationContext.class.getClassLoader();
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                String filename = file.getAbsolutePath();
                if (filename.endsWith(".class")) {
                    String classUrl = filename.substring(filename.indexOf("com"), filename.indexOf(".class")).replace("\\", ".");
                    //加载到JVM中去。
                    Class clazz = classLoader.loadClass(classUrl);
                    classeList.add(clazz);
                }
            }
        }
        return classeList;
    }
}

c. 获取到所有的class后,我是不是要解析class,将对应的信息分装到BeanDefinition中,并且放入到BeanDefinitionMap,以及将实现了BeanPostProcessor的类添加到BeanPostProcessorList中。所以我们在启动各类中,添加字段BeanDefinitionMap,和BeanPostProcessorList

public class MySpringApplicationContext{

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

	private List<BeanPostProcess> beanPostProcessList = new ArrayList<BeanPostProcess>();
	
	public MySpringApplicationContext(Class clazz) {//这里就是传入自定义的配置类。
        //扫描
        try {
            scan(clazz);
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }
    //扫描方法
	private void scan(Class clazz) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取扫描路径
        if (!clazz.isAnnotationPresent(ComponentScan.class)) {
            throw new RuntimeException("未找到扫描路径");
        }
        //获取扫描路径
        ComponentScan componentScanAnnotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);//获取配置类上的 ComponentScan
        String scanPath = componentScanAnnotation.value(); //获取路径
        //获取路径下所有的class文件
        List<Class> classeList = getBeanClass(scanPath);
        for (Class aClass : classeList) {
            if (aClass.isAnnotationPresent(Component.class)) {
                Component componentAnnotation = (Component) aClass.getAnnotation(Component.class);
                String beanName = componentAnnotation.value();
                if ("".equals(beanName)) {
                    beanName = aClass.getSimpleName();
                    String smial = beanName.substring(0, 1).toLowerCase();
                    beanName = smial + beanName.substring(1);
                }
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setClazz(aClass);
                //判断是否实现了BeanPostProcessor
                if (BeanPostProcess.class.isAssignableFrom(aClass)) {
                    BeanPostProcess instance = (BeanPostProcess) aClass.getDeclaredConstructor().newInstance();
                    beanPostProcessList.add(instance);
                }
                //判断是否是单利还是多例
                if (aClass.isAnnotationPresent(Scope.class)) {
                    Scope scopeAnnotation = (Scope) aClass.getAnnotation(Scope.class);
                    String scopeScope = scopeAnnotation.value();
                    if ("propoto".equals(scopeScope)) {
                        beanDefinition.setScope("propoto");
                    } else {
                        beanDefinition.setScope("singleton");
                    }

                } else {
                    beanDefinition.setScope("singleton");
                }
                beanDefinitionMap.put(beanName, beanDefinition);
            }
        }

    }
    //根据路径获取class文件
    private List<Class> getBeanClass(String scanPath) throws ClassNotFoundException {
        List<Class> classeList = new ArrayList<>();
        scanPath = scanPath.replace(".", "/");
        URL resource = ClassLoader.getSystemResource(scanPath);
        File dir = new File(resource.getFile());
        //获取启动类的加载器
        ClassLoader classLoader = MySpringApplicationContext.class.getClassLoader();
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                String filename = file.getAbsolutePath();
                if (filename.endsWith(".class")) {
                    String classUrl = filename.substring(filename.indexOf("com"), filename.indexOf(".class")).replace("\\", ".");
                    //加载到JVM中去。
                    Class clazz = classLoader.loadClass(classUrl);
                    classeList.add(clazz);
                }
            }
        }
        return classeList;
    }
}

d. 创建bean的方法。但是我是要创建所有的bean。在我上一步中,我不是将所有的类信息都放到了BeanDefinitionMap中去了么。那么我就只要遍历这个Map,根据Map中的beanDefinition创建bean.

public class MySpringApplicationContext {


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

    private Map<String, Object> singtleObjects = new HashMap<>();

    private List<BeanPostProcess> beanPostProcessList = new ArrayList<BeanPostProcess>();


    public MySpringApplicationContext(Class clazz) {
        //扫描
        try {
            scan(clazz);
            //遍历所有的BedefinitionMap
            doWhileByBeanDefinitionMap();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void scan(Class clazz) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取扫描路径
        if (!clazz.isAnnotationPresent(ComponentScan.class)) {
            throw new RuntimeException("未找到扫描路径");
        }
        //获取扫描路径
        ComponentScan componentScanAnnotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);
        String scanPath = componentScanAnnotation.value();
        //获取路径下所有的class文件
        List<Class> classeList = getBeanClass(scanPath);
        for (Class aClass : classeList) {
            if (aClass.isAnnotationPresent(Component.class)) {
                Component componentAnnotation = (Component) aClass.getAnnotation(Component.class);
                //获取Component的值作为beanName
                String beanName = componentAnnotation.value();
                //如果没有值 将类名的首字母小写。
                if ("".equals(beanName)) {
                    beanName = aClass.getSimpleName();
                    String smial = beanName.substring(0, 1).toLowerCase();
                    beanName = smial + beanName.substring(1);
                }
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setClazz(aClass);
                //判断是否实现了BeanPostProcessor
                if (BeanPostProcess.class.isAssignableFrom(aClass)) {
                    BeanPostProcess instance = (BeanPostProcess) aClass.getDeclaredConstructor().newInstance();
                    beanPostProcessList.add(instance);
                }
                //判断是否是单利还是多例
                if (aClass.isAnnotationPresent(Scope.class)) {
                    Scope scopeAnnotation = (Scope) aClass.getAnnotation(Scope.class);
                    String scopeScope = scopeAnnotation.value();
                    if ("propoto".equals(scopeScope)) {
                        beanDefinition.setScope("propoto");
                    } else {
                        beanDefinition.setScope("singleton");
                    }

                } else {
                    beanDefinition.setScope("singleton");
                }
                beanDefinitionMap.put(beanName, beanDefinition);
            }
        }

    }

    private List<Class> getBeanClass(String scanPath) throws ClassNotFoundException {
        List<Class> classeList = new ArrayList<>();
        scanPath = scanPath.replace(".", "/");
        URL resource = ClassLoader.getSystemResource(scanPath);
        File dir = new File(resource.getFile());
        //获取启动类的加载器
        ClassLoader classLoader = MySpringApplicationContext.class.getClassLoader();
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                String filename = file.getAbsolutePath();
                if (filename.endsWith(".class")) {
                    String classUrl = filename.substring(filename.indexOf("com"), filename.indexOf(".class")).replace("\\", ".");
                    Class clazz = classLoader.loadClass(classUrl);
                    classeList.add(clazz);
                }
            }
        }
        return classeList;
    }

	//遍历所有的BeanDefinitionMap
    private void doWhileByBeanDefinitionMap() throws IllegalAccessException, InstantiationException {

        for (Map.Entry<String, BeanDefinition> stringBeanDefinitionEntry : beanDefinitionMap.entrySet()) {
            String beanName = stringBeanDefinitionEntry.getKey();
            Object beanObject = createBean(beanName);
            singtleObjects.put(beanName, beanObject);
        }

    }
 	//创建bean
    private Object createBean(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        Object beanObject = null;
        try {
            Class clazz = beanDefinition.getClazz();
            beanObject = clazz.newInstance();
            //依赖注入
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    field.setAccessible(true);
                    //注意这里因为没有实现getBean方法所有先用createBean代替
                    //getBean实现有如下
                    // field.set(beanObject,getBean(field.getName()));
                    field.set(beanObject, createBean(field.getName()));
                }
            }
            //初始化前
            for (Method declaredMethod : clazz.getDeclaredMethods()) {
                if (declaredMethod.isAnnotationPresent(PostConstruct.class)) {
                    declaredMethod.invoke(beanObject);
                }
            }

            //初始化
            if (beanObject instanceof InitalitionBean) {
                ((InitalitionBean) beanObject).afterPropertiesSet();
            }

            //初始化后
            for (BeanPostProcess beanPostProcess : beanPostProcessList) {
                beanObject = beanPostProcess.afterBeanPostProcess(beanName,beanObject);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        if (beanObject==null) {
            throw new RuntimeException("创建Bean失败");
        }
        return beanObject;
    }


}

e. 最后创建一个getBean方法。

public class MySpringApplicationContext {


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

    private Map<String, Object> singtleObjects = new HashMap<>();

    private List<BeanPostProcess> beanPostProcessList = new ArrayList<BeanPostProcess>();


    public MySpringApplicationContext(Class clazz) {
        //扫描
        try {
            scan(clazz);
            doWhileByBeanDefinitionMap();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    private void scan(Class clazz) throws IOException, ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取扫描路径
        if (!clazz.isAnnotationPresent(ComponentScan.class)) {
            throw new RuntimeException("未找到扫描路径");
        }
        //获取扫描路径
        ComponentScan componentScanAnnotation = (ComponentScan) clazz.getAnnotation(ComponentScan.class);
        String scanPath = componentScanAnnotation.value();
        //获取路径下所有的class文件
        List<Class> classeList = getBeanClass(scanPath);
        for (Class aClass : classeList) {
            if (aClass.isAnnotationPresent(Component.class)) {
                Component componentAnnotation = (Component) aClass.getAnnotation(Component.class);
                String beanName = componentAnnotation.value();
                if ("".equals(beanName)) {
                    beanName = aClass.getSimpleName();
                    String smial = beanName.substring(0, 1).toLowerCase();
                    beanName = smial + beanName.substring(1);
                }
                BeanDefinition beanDefinition = new BeanDefinition();
                beanDefinition.setClazz(aClass);
                //判断是否实现了BeanPostProcessor
                if (BeanPostProcess.class.isAssignableFrom(aClass)) {
                    BeanPostProcess instance = (BeanPostProcess) aClass.getDeclaredConstructor().newInstance();
                    beanPostProcessList.add(instance);
                }
                //判断是否是单利还是多例
                if (aClass.isAnnotationPresent(Scope.class)) {
                    Scope scopeAnnotation = (Scope) aClass.getAnnotation(Scope.class);
                    String scopeScope = scopeAnnotation.value();
                    if ("propoto".equals(scopeScope)) {
                        beanDefinition.setScope("propoto");
                    } else {
                        beanDefinition.setScope("singleton");
                    }

                } else {
                    beanDefinition.setScope("singleton");
                }
                beanDefinitionMap.put(beanName, beanDefinition);
            }
        }

    }

    private List<Class> getBeanClass(String scanPath) throws ClassNotFoundException {
        List<Class> classeList = new ArrayList<>();
        scanPath = scanPath.replace(".", "/");
        URL resource = ClassLoader.getSystemResource(scanPath);
        File dir = new File(resource.getFile());
        //获取启动类的加载器
        ClassLoader classLoader = MySpringApplicationContext.class.getClassLoader();
        if (dir.isDirectory()) {
            File[] files = dir.listFiles();
            for (File file : files) {
                String filename = file.getAbsolutePath();
                if (filename.endsWith(".class")) {
                    String classUrl = filename.substring(filename.indexOf("com"), filename.indexOf(".class")).replace("\\", ".");
                    Class clazz = classLoader.loadClass(classUrl);
                    classeList.add(clazz);
                }
            }
        }
        return classeList;
    }


    private void doWhileByBeanDefinitionMap() throws IllegalAccessException, InstantiationException {

        for (Map.Entry<String, BeanDefinition> stringBeanDefinitionEntry : beanDefinitionMap.entrySet()) {
            String beanName = stringBeanDefinitionEntry.getKey();
            Object beanObject = createBean(beanName);
            singtleObjects.put(beanName, beanObject);
        }

    }

    private Object createBean(String beanName) {
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        Object beanObject = null;
        try {
            Class clazz = beanDefinition.getClazz();
            beanObject = clazz.newInstance();
            //依赖注入
            for (Field field : clazz.getDeclaredFields()) {
                if (field.isAnnotationPresent(Autowired.class)) {
                    field.setAccessible(true);
                    field.set(beanObject,getBean(field.getName()));
                }
            }
            //初始化前
            for (Method declaredMethod : clazz.getDeclaredMethods()) {
                if (declaredMethod.isAnnotationPresent(PostConstruct.class)) {
                    declaredMethod.invoke(beanObject);
                }
            }

            //初始化
            if (beanObject instanceof InitalitionBean) {
                ((InitalitionBean) beanObject).afterPropertiesSet();
            }

            //初始化后
            for (BeanPostProcess beanPostProcess : beanPostProcessList) {
                beanObject = beanPostProcess.afterBeanPostProcess(beanName,beanObject);
            }
        } catch (InstantiationException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        if (beanObject==null) {
            throw new RuntimeException("创建Bean失败");
        }
        return beanObject;
    }

    public Object getBean(String beanName) {
        if (!beanDefinitionMap.containsKey(beanName)) {
            throw new RuntimeException("未找到bean对象");
        }
        BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
        if (beanDefinition.getScope().equals("singleton")) {
            return singtleObjects.get(beanName);
        } else {
            return createBean(beanName);
        }
    }

}

以上简单的spring就手写好了,现在我们测试一下。

  1. 创建一个Test类
public class Test {

    public static void main(String[] args) {
        MySpringApplicationContext app = new MySpringApplicationContext(MyConfig.class);
        UserService userService = (UserService) app.getBean("userService");
        userService.test();
        userService.orderServiceTest();

        OrderService orderService = (OrderService) app.getBean("orderService");
        System.out.println(orderService.getName());
    }

}
  1. 创建一个 UserService和OrderService,并且给UserService注入OrderService.
    UserService:
@Component
public class UserService implements InitalitionBean {

    @Autowired
    private OrderService orderService;

    @PostConstruct
    public void test(){
        System.out.println("UserService初始化前");
    }

    public void orderServiceTest(){
        orderService.test();
    }

    @Override
    public void afterPropertiesSet() {
        System.out.println("UserService初始化方法");
    }
}
@Component
public class OrderService {

    public void test(){
        System.out.println("orderService创建成功,正常调用");
    }

}

  1. 创建一个初始化后置器MyBeanPostProcessor
@Component
public class MyBeanPostProcessor implements BeanPostProcess {
    @Override
    public Object afterBeanPostProcess(String beanName, Object bean) {
        System.out.println(beanName+"初始化后");
        return bean;
    }
}
  1. 当然还有我们的配置类 MyConfig
@ComponentScan("com.project.service")
public class MyConfig {
}

  1. 最后我们执行下Test.main方法,结果如下 。可以看到我们的代码是没有问题的,而且我们最终的目录如下。
    在这里插入图片描述

OK!! 搞定 ^ _ ^

Yout con’t live for other people. You have to be true to yourself .
忠于自己,不必未别人而活。

                                                                                                                                                                             ———摘自有道翻译

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值