立聪堂德州十三局店 发表于 2024-5-16 18:47:15

手写Spring底层机制

手写Spring底层机制

IOC容器

    //定义 BeanDefinitionMap 存放 beanDefinition
    private ConcurrentHashMap<String,BeanDefinition> beanDefinitionMap =
            new ConcurrentHashMap<>();

    //定义 singletonObjects 存放 单例
    private ConcurrentHashMap<String,Object> singletonObjects =
            new ConcurrentHashMap<>();


    //定义beanPostProcessorList 存放 BeanPostProcessor
    private ArrayList<BeanPostProcessor> beanPostProcessorList=
            new ArrayList<>();构造器

//构造器
public ZyApplicationContext(Class configClass) {
    this.configClass = configClass;

    beanDefinitionsByScan();

    //初始化单例池
    initSingletonObjects();
}扫描包

private void beanDefinitionsByScan() {
      //获得扫描的包
      ComponentScan componentScan =
                (ComponentScan)this.configClass.getDeclaredAnnotation(ComponentScan.class);

      //获取路径
      String path = componentScan.value();

      path = path.replace(".","/");
      //获取工作路径
      ClassLoader classLoader = ZyApplicationContext.class.getClassLoader();

      URL resource = classLoader.getResource(path);

      File file = new File(resource.getFile());
      if (file.isDirectory()){
            File[] files = file.listFiles();
            for (File f : files) {
                //获取绝对路径
                String fileAbsolutePath = f.getAbsolutePath();
                if (fileAbsolutePath.endsWith(".class")) {
                  //获取className
                  String className = fileAbsolutePath.substring(fileAbsolutePath.lastIndexOf("\\") + 1, fileAbsolutePath.indexOf(".class"));

                  String fullPath = path.replace("/", ".") + "." + className;

                  try {
                        Class<?> clazz = classLoader.loadClass(fullPath);
                        if (clazz.isAnnotationPresent(Component.class)) {

                            //初始化beanPostProcessorList
                            if (BeanPostProcessor.class.isAssignableFrom(clazz)){
                              BeanPostProcessor beanPostProcessor =
                                    (BeanPostProcessor)clazz.newInstance();
                              beanPostProcessorList.add(beanPostProcessor);
                              continue;
                            }


                            //处理className
                            String value = clazz.getDeclaredAnnotation(Component.class).value();
                            if ("".equals(value)){
                              className = StringUtils.uncapitalize(className);
                            }else {
                              className = value;
                            }
                            System.out.println("是一个bean 类名= " + className);
                            //设置 beanDefinition
                            BeanDefinition beanDefinition = new BeanDefinition();
                            //设置scope
                            if (clazz.isAnnotationPresent(Scope.class)){
                              beanDefinition.setScope(clazz.getDeclaredAnnotation(Scope.class).value());
                            }else{
                              beanDefinition.setScope("singleton");
                            }
                            beanDefinition.setClazz(clazz);

                            //放入 beanDefinitionMap
                            beanDefinitionMap.put(className,beanDefinition);




                        } else {
                            System.out.println("不是一个bean 类名= " + className);
                        }
                  } catch (Exception e) {
                        throw new RuntimeException(e);
                  }
                }
            }
      }
    }初始化单例池

private void initSingletonObjects() {
      Enumeration<String> keys = beanDefinitionMap.keys();
      while (keys.hasMoreElements()){
            String beanName = keys.nextElement();
            BeanDefinition beanDefinition = beanDefinitionMap.get(beanName);
            String scope = beanDefinition.getScope();
            if ("singleton".equals(scope)){
                Object bean = createBean(beanDefinition,beanName);
                singletonObjects.put(beanName,bean);
            }

      }
    }getBean()

public Object getBean(String name){
      if (beanDefinitionMap.containsKey(name)){
            BeanDefinition beanDefinition = beanDefinitionMap.get(name);
            String scope = beanDefinition.getScope();
            if ("singleton".equals(scope)){
                return singletonObjects.get(name);
            }else{
                return createBean(beanDefinition,name);
            }
      }
      return null;
    }createBean()

private Object createBean(BeanDefinition beanDefinition,String beanName){
      try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();
            
            return instance;
      } catch (InstantiationException e) {
            throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
      }
    }依赖注入


[*]加入到createBean()中
private Object createBean(BeanDefinition beanDefinition,String beanName){
      try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();

            //依赖注入
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (declaredField.isAnnotationPresent(Autowired.class)){
                  if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
                        //获的字段名
                        String fieldName = declaredField.getName();
                        //获取实例
                        Object bean = getBean(fieldName);
                        declaredField.setAccessible(true);
                        declaredField.set(instance,bean);
                  }
                }
            }

         
            return instance;
      } catch (InstantiationException e) {
            throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
      }
    }后置处理器


[*]加入到createBean()中
private Object createBean(BeanDefinition beanDefinition,String beanName){
      try {
            Class clazz = beanDefinition.getClazz();
            Object instance = clazz.getDeclaredConstructor().newInstance();

            //依赖注入
            Field[] declaredFields = clazz.getDeclaredFields();
            for (Field declaredField : declaredFields) {
                if (declaredField.isAnnotationPresent(Autowired.class)){
                  if (declaredField.getDeclaredAnnotation(Autowired.class).required()){
                        //获的字段名
                        String fieldName = declaredField.getName();
                        //获取实例
                        Object bean = getBean(fieldName);
                        declaredField.setAccessible(true);
                        declaredField.set(instance,bean);
                  }
                }
            }

            //后置处理器 before()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessBeforeInitialization(instance, beanName);
                if (current!=null){
                  instance = current;
                }

            }


            //初始化bean
            if (instance instanceof InitializingBean){
                try {
                  ((InitializingBean)instance).afterPropertiesSet();
                } catch (Exception e) {
                  throw new RuntimeException(e);
                }
            }



            //后置处理器 after()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessAfterInitialization(instance, beanName);
                if (current!=null){
                  instance = current;
                }

            }


            System.out.println("");
            System.out.println("-------------------------------------");
            System.out.println("");
            return instance;
      } catch (InstantiationException e) {
            throw new RuntimeException(e);
      } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
      } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
      } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
      }
    }AOP


[*]AOP需要在后置处理器的before方法中实现
@Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
      System.out.println("ZyBeanPostProcessor后置处理器-After-beanName= "+beanName);


      //aop实现

      if("smartDog".equals(beanName)) {
            Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {


                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                  Object result = null;

                  if ("getSum".equals(method.getName())) {
                        SmartAnimalAspect.showBeginLog();
                        result = method.invoke(bean, args);
                        SmartAnimalAspect.showBeginLog();
                  }else {
                        result = method.invoke(bean, args);//执行目标方法
                  }

                  return result;
                }
            });
            return proxyInstance;
      }

      return bean;
    }几个Spring的题目

1.单例/多例怎么实现的?@scope为什么可以实现?
回答:@scope 的value属性可以设置为singleton /prototype
通过getBean()方法 如果bean中的属性scope为singleton 就从单例池直接拿,如果是prototype 就调用createBean()创建一个实例
2.怎样实现依赖注入?@Autowired Spring容器怎样实现依赖注入?
回答: 遍历clazz的所有属性 通过@Autowired注解 如果有 先获取字段名 再通过getBean()获取对应的bean 末了用filed.set()方法将实例的该属性设置为 获取到的bean 实现依赖注入
3.后置处理器 为什么在创建bean 时 调用bean 的 init方法初始化前/后 调用?
//后置处理器 before()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessBeforeInitialization(instance, beanName);
                if (current!=null){
                  instance = current;
                }

            }


            //初始化bean
            if (instance instanceof InitializingBean){
                try {
                  ((InitializingBean)instance).afterPropertiesSet();
                } catch (Exception e) {
                  throw new RuntimeException(e);
                }
            }



            //后置处理器 after()
            //遍历 beanPostProcessorList
            for (BeanPostProcessor beanPostProcessor : beanPostProcessorList) {
                Object current = beanPostProcessor.
                        postProcessAfterInitialization(instance, beanName);
                if (current!=null){
                  instance = current;
                }

            }4.后置处理器和AOP有什么关系,Spring Aop怎样实现??
回答:aop的实现实在后置处理器的before中实现的,底层利用动态代理
//aop实现

      if("smartDog".equals(beanName)) {
            Object proxyInstance = Proxy.newProxyInstance(ZyBeanPostProcessor.class.getClassLoader(), bean.getClass().getInterfaces(), new InvocationHandler() {


                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                  Object result = null;

                  if ("getSum".equals(method.getName())) {
                        SmartAnimalAspect.showBeginLog();
                        result = method.invoke(bean, args);
                        SmartAnimalAspect.showBeginLog();
                  }else {
                        result = method.invoke(bean, args);//执行目标方法
                  }

                  return result;
                }
            });
            return proxyInstance;
      }

      return bean;
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 手写Spring底层机制