灵活运用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自动管理,极大的提高了编码质量。

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