如何理解BeanPostProcessor

==> 學習彙總(持續更新)
==> 從零搭建後端基礎設施系列(一)-- 背景介紹


  • 原始片段
    創建bean的時候,有這麼一段代碼,遍歷所有實現了BeanPostProcessor這個接口的類,並一個個調用其中的方法。

    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    	for (BeanPostProcessor bp : getBeanPostProcessors()) {
    		if (bp instanceof InstantiationAwareBeanPostProcessor) {
    			InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    			Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    			if (result != null) {
    				return result;
    			}
    		}
    	}
    	return null;
    }
    

    相信看到這裏,就差不多可以理解這個接口的用途。這就是框架的可擴展性,把結構搭出來,然後你可以往裏面填東西。

  • 自制一個簡單的case

    • 接口類

      interface BeanProcessor {
      	void beforeCreate();
      	void aroundCreate();
      	void afterCreate();
      }
      
    • 實現類A

      public class A implements BeanProcessor{
      
      	@Override
       	public void beforeCreate() {
      		System.out.println("A創建之前做點啥");
      	}
      
       	@Override
      	public void aroundCreate() {
      		System.out.println("A正在創建的時候做點啥");
      	}
      
      	@Override
      	public void afterCreate() {
      		System.out.println("A創建完了做點啥");
      	}
      }
      
    • 實現類B

      public class B implements BeanProcessor{
      
      	@Override
       	public void beforeCreate() {
      		System.out.println("B創建之前做點啥");
      	}
      
       	@Override
      	public void aroundCreate() {
      		System.out.println("B正在創建的時候做點啥");
      	}
      
      	@Override
      	public void afterCreate() {
      		System.out.println("B創建完了做點啥");
      	}
      }
      
    • 業務邏輯

      public class Main {
      	public static void main(String[] args) {
      		Reflections reflections = new Reflections("com.acme.test");
              		Set<Class<? extends BeanProcessor>> subClass = reflections.getSubTypesOf(BeanProcessor.class);
              System.out.println("開始創建……");
              subClass.forEach(v -> {
                  try {
                      v.newInstance().beforeCreate();
                  } catch (Throwable e) {
                      e.printStackTrace();
                  }
              });
              System.out.println("正在創建……");
              subClass.forEach(v -> {
                  try {
                      v.newInstance().aroundCreate();
                  } catch (Throwable e) {
                      e.printStackTrace();
                  }
              });
              System.out.println("結束創建……");
              subClass.forEach(v -> {
                  try {
                      v.newInstance().afterCreate();
                  } catch (Throwable e) {
                      e.printStackTrace();
                  }
              });
          }
      }
      

    然後我們以後還有CDEFG等等類似的需求,都可以這樣擴展。

  • 思考
    爲什麼挑這個點講呢?其實是最近對於代碼重構有自己的一些想法。大家都在瘋狂去diss業務代碼,卻沒有認真的去思考自己寫的代碼是否合格,可擴展性真的不是說一說,要落到實地去,這樣既能提高自己的水平,還能惠及後人,接手項目的時候,就不再是"接鍋俠"了。總結一點就是,不管是什麼代碼,永遠記住,將基本或者大概率不會變的邏輯封裝起來,將可能或頻繁變更的點,以接口的形式暴露出來。這樣,不管來多少個類似的需求,那不是輕輕鬆鬆的就搞定了嗎?

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