項目中經常會遇到要向代碼中添加定時任務(類似消費線程),通常這樣的定時任務都是臨時加入。除此外,項目中的任務都很相似,所以在設計的時候都會爲其添加一個超類(或者接口),因此所有的定時任務都要繼承這個超類。這些任務通常數量不少,十幾個甚至二十幾個,相當於要管理至少十幾個實例,非常繁瑣。因此我們如果能知道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自動管理,極大的提高了編碼質量。