spring 框架脉络梳理

  1. spring源码入口

    DispatchServlet ,继承FrameworkServlet ->HttpServletBean->org.springframework.web.servlet.HttpServlet->javax.servlet.GenericServlet

    生命周期:

    • init() ,处于HttpServletBean
    • service()->处理url,由web容器调用
      • doGet()
      • doPost
    • destory()

    源码:70%猜测+30%验证

  2. 源码注解模仿

    @Controller

    @RequestMapping

    @Autowired

    @RequestParam

    @Service

  3. 初始化过程

    1. DispatchServlet 初始化九大组件,初始化容器,servletBean
    protected void initStrategies(ApplicationContext context) {
    		initMultipartResolver(context);
    		initLocaleResolver(context);
    		initThemeResolver(context);
    		initHandlerMappings(context);
    		initHandlerAdapters(context);
    		initHandlerExceptionResolvers(context);
    		initRequestToViewNameTranslator(context);
    		initViewResolvers(context);
    		initFlashMapManager(context);
    	}
    
    1. FrameworkServlet,contextConfigLocation->配置文件路径

    2. org.springframework.web.servlet.HttpServletBean

      init()->getServletConfig 获取配置

      关注:initServletBean()

    3. javax.servlet.GenericServlet

      private transient ServletConfig config,获取配置

  4. spring精华设计思想

    public void init(ServletConfig conf) throws ServletException {
            //1、加载配置文件
            //2、扫描相关类
            //3、初始化类,放入ioc容器
            //4、完成依赖注入di
            //5、建立url与method对应关系
        	//6、调用服务 (service())
        }
    
  5. 知识点实现

    1. String 转换成Pattern

        Pattern pattern = java.util.regex.Pattern.compile("/query.*");
      
    2. Pattern比较

       Matcher matcher = pattern.matcher("/query.*");
       if (!matcher.matches()){}
      
    3. spring boot 触发自定义servlet

      1、 @WebServlet

      步骤:

      • 触发扫描:@ServletComponentScan ,此注解下的目录及子目录下的有 @WebServlet注解的类将被触发
      • @WebServlet( urlPatterns = { "/*"},loadOnStartup=1)

      2、注册方式

      	@Bean
          public ServletRegistrationBean getServletRegistrationBean() { 
              ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyDispatchServlet());
              registrationBean.addUrlMappings("/*");  //访问拦截的路径
              return bean;
          }
      }
      
    4. 解析配置文件

       private Properties config=new Properties();
       InputStream in = this.getClass().getClassLoader().getResourceAsStream("init.properties");
       config.load(in);
      
    5. 将string 地址转换为url地址

      //1、scanPackage=com.example.spring.mini,由包路径转换成文件路径
      //classLoad.getResource()以classpath 为基准.
      //class.getResource()已当前类路径为参考
       URL url = this.getClass().getClassLoader().getResource( scanPackage.replaceAll("\\.", "/"));
       File classpath = new File(url.getFile());
      
    6. 根据类名路径获取反射对象

      Class<?> clazz = Class.forName(className)
      
    7. 利用反射获取注解

      Controller controller=clazz.getAnnotation(Controller.class)
      
    8. 判断类是否使用了某个注解

       if (clazz.isAnnotationPresent(Controller.class))
      
    9. 注解实现

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

      @Target 作用范围

      @Retention 注解可读取时间

      @Inherited 是否可以继承

    10. String 的replace与replaceAll区别

      replace,替换字符串或者字符

      replaceAll,可以根据正则表达式匹配

      相同点:匹配上的都会全部替换

  6. 问题

    • spring 的bean是否是线程安全的?

      spring 的bean 是类初始化的时候,扫描配置、注解而初始化的,不对类做任何操作,类的定义是业务操作的,与spring无关;

    • spring 的bean什么时候被回收的?

      与spring 的类型相关,如singleton、prototype、session 、request

      spring中的bean默认是singleton,全局的

      GC的回收原则,bean的引用没有指向

      spring的bean存储再map中的,ioc容器本身就是单例,本身不会消失。singleton对象随着spring的消失与存亡

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章