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的消失與存亡

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