Spring 3-在运行时基于另一个对象属性的动态自动装配


问题内容

我正在开发Spring 3.1 MVC应用程序,对于我的一种情况,我不得不编写DAO的两个实现。我想知道如何根据另一个对象的属性在服务层中自动布线。

例如,

    class Vehicle {
        private name;
        private type;
        ..
        ..
        ..
    }

    @Service
    class VehicleServiceImpl implements VehicleService {

            // There are two implementations to this DAO
            // if Vehicle.type == "CAR", inject CarDAO
            // if Vehicle.type == "TRAIN", inject TrainDAO 
            @Autowired
            private VehicleDAO vehicleDAO ;

    }

    @Repository
    class CarDAO implements VehicleDAO {

    }

    @Repository
    class TrainDAO implements VehicleDAO {

    }

如果我的车辆是汽车,则需要为CarDAO自动接线,如果是火车,则需要为TrainDAO自动接线

在Spring 3.1中实现此目标的最佳方法是什么。

我希望使用上下文属性占位符或@Qualifier批注,但这两种都限于基于某些属性的查找。我不确定如何根据另一个对象的属性在运行时执行此操作。


问题答案:

我的解决方案如下:

VehicleDao接口中的isResponsibleFor方法:

interface VehicleDao {
    public boolean isResponsibleFor(Vehicle vehicle);
}

示例实现:

@Repository
class CarDAO implements VehicleDAO {
    public boolean isResponsibleFor(Vehicle vehicle) {
        return "CAR".equals(vehicle.getType());
    }
}

然后自动连接VehicleService中所有VehicleDao实现的列表:

public class VehicleServiceImpl implements VehicleService {

    @Autowired
    private List<VehicleDao> vehicleDaos;

    private VehicleDao daoForVehicle(Vehicle vehicle) {
         foreach(VehicleDao vehicleDao : vehicleDaos) {
              if(vehicleDao.isResponsibleFor(vehicle) {
                   return vehicleDao;
              }
         }

         throw new UnsupportedOperationException("unsupported vehicleType");
    }

    @Transactional
    public void save(Vehicle vehicle) {
         daoForVehicle(vehicle).save(vehicle);
    }
}

这样做的好处是,以后再添加新的vehicleType时,您无需修改​​服务-您只需要添加新的VehicleDao实现。