项目中经常会遇到要向代码中添加定时任务(类似消费线程),通常这样的定时任务都是临时加入。除此外,项目中的任务都很相似,所以在设计的时候都会为其添加一个超类(或者接口),因此所有的定时任务都要继承这个超类。这些任务通常数量不少,十几个甚至二十几个,相当于要管理至少十几个实例,非常繁琐。因此我们如果能知道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自动管理,极大的提高了编码质量。