靈活運用Spring容器中的 getBeansOfType(Class type)函數

項目中經常會遇到要向代碼中添加定時任務(類似消費線程),通常這樣的定時任務都是臨時加入。除此外,項目中的任務都很相似,所以在設計的時候都會爲其添加一個超類(或者接口),因此所有的定時任務都要繼承這個超類。這些任務通常數量不少,十幾個甚至二十幾個,相當於要管理至少十幾個實例,非常繁瑣。因此我們如果能知道Spring中的這個方法getBeansOfType,併合理的使用它,會使我們的操作變得非常舒服。這裏我就不直接提供公司的代碼,而是用新的例子代替,簡要的說明其思想。

public interface Car{
    public void dispatch();
}
 
@Component
public class SedanCar implements Car{
    @override
    public void dispatch(){
        System.out.println("Sedan car coming!");
    }
} 
 
@Component
public class SportsCar implements Car{
    @override
    public void sayHello(){
        System.out.println("Sports car coming!");
    }
}  

上述代碼很簡單,一個接口Car,SportsCar 和SedanCar分別繼承Car接口,哪種車被調度到了,都會打印各自的語句,即調用dispatch方法。@Component註解會將SportsCar 和SedanCar實例化,並納入spring容器的管理範圍。

@Component
public class SpringContextUtil implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        SpringContextUtil.applicationContext = applicationContext;
    }
    public static <T> List<T> getBeanListOfType(Class<T> clazz) {
        List<T> result = new ArrayList<>();
        Map<String, T> map = applicationContext.getBeansOfType(clazz);
        if (null != map) {
            result.addAll(map.values());
        }
        return result;
    }
}

上述代碼是繼承了ApplicationContextAware 接口,並實現了setApplicationContext函數,通過該函數我們能很方便的拿到Spring容器對象ApplicationContext 。getBeanListOfType函數可以爲我們返回Spring容器中指定的類的list。

public class DispatchCenter{
    private List<Car> carList;
    public void dispatchCar(){
        while(true){
            carList.forEach(car->{car.dispatch()});
            Thread.sleep(1000);
        }
    }
    public void init() {
        carList = SpringContextUtil.getBeanListOfType(car);
        dispatchCar();
    }
    public void destory(){}
}

上述代碼是一個調度中心,可以通過getBeanListOfType函數獲取Car類的全部實例,並調度所有的車輛。**從這裏我們能看出getBeansOfType函數爲我們帶來的方便性了,非常方便的管理全部Car的實例對象。如果想爲調度中心添加新的車輛,只需要讓車輛類繼承Car接口,然後實現dispatch函數即可,不用修改其他的類。最後問題來了,**該怎麼樣讓調度中心運行起來呢?

@Configuration
public class DispatchCenterManage{
    @Bean(name = "pushDataSource", destroyMethod = "destory", initMethod = "init")
    public DispatchCenter dispatchCenterStart(){
        return new DispatchCenter();
    }
}

或者

<bean id="pushDataSource"
          class="com.DispatchCenter"
          init-method="init" destroy-method="destory"></bean>

上述代碼通過@Bean註解顯示告訴Spring以函數指明的方式實例化DispatchCenter對象,並交由Spring容器管理。Spring容器的在啓動時,實例化DispatchCenter對象,並且執行初始化方法init(),這樣調度中心就運行起來的。全程,我沒有手動實例化任何對象,全部交由Spring自動管理,極大的提高了編碼質量。

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