[SPRING] Spring 3 - 다른 객체 속성을 기반으로 런타임에 동적 Autowiring
SPRINGSpring 3 - 다른 객체 속성을 기반으로 런타임에 동적 Autowiring
저는 Spring 3.1 MVC 어플리케이션을 작업하고 있습니다. 시나리오 중 하나에 대해 DAO의 두 가지 구현을 작성해야했습니다. 나는 이것을 서비스 레이어에서 autowire하는 법을 알고 싶다. 다른 객체의 속성을 기반으로합니다.
예를 들어,
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 주석 중 하나를 사용하고 싶었지만 두 속성 모두 일부 속성을 기반으로 조회하는 데 제한이 있습니다. 다른 개체의 속성을 기반으로 런타임에이 작업을 수행하는 방법을 잘 모르겠습니다.
해결법
-
==============================
1.내 솔루션은 다음과 같습니다 :
내 솔루션은 다음과 같습니다 :
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 구현 목록을 autowire합니다.
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 구현을 추가하기 만하면됩니다.
-
==============================
2.이 전략을 수행하기위한 더 깨끗한 옵션이 있습니다. 우리는 Spring이 제어 할 수있는 bean을 어디서나 주입 할 수있을 정도로 똑똑하다는 것을 알고 있으므로 @Autowire 또는 @Resource 주석으로 VehicleDAO를 볼 때 그 구현을 정확하게 주입 할 것입니다.
이 전략을 수행하기위한 더 깨끗한 옵션이 있습니다. 우리는 Spring이 제어 할 수있는 bean을 어디서나 주입 할 수있을 정도로 똑똑하다는 것을 알고 있으므로 @Autowire 또는 @Resource 주석으로 VehicleDAO를 볼 때 그 구현을 정확하게 주입 할 것입니다.
이 점을 염두에두면 Spring에 의존성 주입을 수행 할 장소를 Map <> 또는 List <>를 사용하여 요청할 수 있습니다.
// Injects the map will all VehicleDAO implementations where key = the // concrete implementation (The default name is the class name, otherwise you // can specify the name explicitly). @Autowired private Map<String, VehicleDAO> vehicleDAO; // When you want to use a specific implementaion of VehicleDAO, just call the // 'get()' method on the map as in: ... vehicleDAO.get("carDAO").yourMethod(); ...
-
==============================
3.Vehicle은 @Model이기 때문에 런타임 값이므로 autowiring 값에 Vehicle을 사용할 수 없습니다.
Vehicle은 @Model이기 때문에 런타임 값이므로 autowiring 값에 Vehicle을 사용할 수 없습니다.
차량은 인수로서 서비스 메소드에 전달되어야합니다.
공용 인터페이스 VehicleService { void doSomething (차량 차량); }
CarDao와 TrainDAO가 동일한 VehicleDao 서비스를 구현한다고 가정 할 때, 다른 말로는별로 의미가 없을 것입니다.
따라서 VehicleServiceImpl에서 getVehicleDao (Vehicle v) {}와 같은 메소드를 작성하여 dao의 올바른 인스턴스를 얻을 것을 권장합니다.
public class VehicleServiceImpl implements VehicleService { @Resource(name="carDAO") private VehicleDao carDAO ; @Resource(name="trainDAO") private VehicleDao trainDAO ; private VehicleDao getDao(Vehicle v){ if(v instanceof Train){ return trainDao; } else if(v instanceof Car) { return carDao; } else { throw new RuntimeException("unsupported vehicle type"); } } void doSomething(Vehicle vehicle){ VehicleDao dao = getDao(vehicle); dao.doSomethind(vehicle); } }
-
==============================
4.한 가지 유의하십시오 : 이전 솔루션은 훌륭하고 간단하지만 봄마다 각 빈의 인스턴스가 만들어집니다.
한 가지 유의하십시오 : 이전 솔루션은 훌륭하고 간단하지만 봄마다 각 빈의 인스턴스가 만들어집니다.
그래서 내 솔루션 인터페이스 대신 추상 클래스 VehicleService를 만드는 것입니다
그런 다음 appContext에서
@Bean @Primary VehicleService paymentProviderService() { return ...new (your requested instance by your own)... }
from https://stackoverflow.com/questions/15284851/spring-3-dynamic-autowiring-at-runtime-based-on-another-object-attribute by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] Spring + REST 웹 서비스로 @RequestBody 또는 @ModelAttribute (0) | 2019.01.13 |
---|---|
[SPRING] 단일 페이지 AngularJS 응용 프로그램을위한 기본 스프링 보안 (세션 관리) 구현 방법 (0) | 2019.01.13 |
[SPRING] 생명주기 이벤트에서 BeanFactoryPostProcessor 및 BeanPostProcessor (0) | 2019.01.13 |
[SPRING] Spring : 주석 중심 트랜잭션 관리자 (0) | 2019.01.13 |
[SPRING] spring.handlers 및 spring.schemas에 대한 이해가 필요합니다. (0) | 2019.01.13 |