Örnek - Generic Bean
Örnek - application.properties
Bu yöntemde iki tane bean yaratılıyor. Hangisinin inject edileceği application.properties ile seçilebiliyor.
Elimizde şöyle bir anotasyon
olsunpackage your.package;
@Retention(RetentionPolicy.RUNTIME)
public @interface InjectDynamicObject {
}
İki tane bean yaratalım
public interface Customer {
public String getName();
}
@Component("customerOne")
public class CustomerOneImpl implements Customer {
@Override
public String getName() {
return "Customer One";
}
}
@Component("customerTwo")
public class CustomerTwoImpl implements Customer {
@Override
public String getName() {
return "Customer Two";
}
}
Çözüm 1 - Kolay Olan
Spring injects the Map with Bean name as String and the Bean itself automagically.
public class CustomerServiceImpl {
// We inject the customer implementations into a Map
@Autowired
private Map<String, Customer> dynamicCustomerWithMap;
// This comes from the property file as a key for the Map
@Value("${dynamic.object.name}")
private String object;
public Customer getDynamicCustomerWithMap() {
return this.dynamicCustomerWithMap.get(object);
}
}
Çözüm 2 - Zor Olan
Bu anotasyonu bir metodda kullanalım ve arayüzümüzü dönelim. Bu servis sınıfı @Autowire edilirse, aşağıda tanımlım olan @Around çalışır ve application.properties dosyasındaki tanımlı bean döner.
@Service
public class CustomerServiceImpl {
private Customer dynamicCustomerWithAspect;
@InjectDynamicObject
public Customer getDynamicCustomerWithAspect() {
return this.dynamicCustomerWithAspect;
}
}
Bu metod için bir Aspect yazalım.
@Component
@Aspect
public class DynamicObjectAspect {
// This comes from the property file
@Value("${dynamic.object.name}")
private String object;
@Autowired
private ApplicationContext applicationContext;
@Pointcut("execution(@com.lofi.springbean.dynamic.InjectDynamicObject * *(..))")
public void beanAnnotatedWithInjectDynamicObject() {
}
@Around("beanAnnotatedWithInjectDynamicObject()")
public Object adviceBeanAnnotatedWithInjectDynamicObject(ProceedingJoinPoint pjp)
throws Throwable {
pjp.proceed();
// Create the bean or object depends on the property file
Object createdObject = applicationContext.getBean(object);
return createdObject;
}
}
Örnek - Metod Parametresi
Elimizde şöyle bir arayüz
olsunpublic enum GeolocationProvider {
GOOGLE_MAP,
GEO_BOUNDARIES
}
public interface GeolocationService {
// to identify support for the provider
GeolocationProvider getGeoProvider();
//method will have the provider specific logic to find the latitude/longitude
Result getLatLongByCity(String city);
}
Bu arayüzü gerçekleştiren iki bean
olsun@Service
public class GoogleMapLocationServiceImpl implements GeolocationService {
@Override
public GeolocationProvider getGeoProvider() {
return GeolocationProvider.GOOGLE_MAP;
}
@Override
public Result getLatLongByCity(String city) {
...
}
}
@Service
public class GeoBoundariesLocationServiceImpl implements GeolocationService {
@Override
public GeolocationProvider getGeoProvider() {
return GeolocationProvider.GEO_BOUNDARIES;
}
@Override
public Result getLatLongByCity(String city) {
...
}
}
Bu iki bean arasında seçim yapmak için metoda parametre
geçeriz@Component
public class GeoLocationProviderContext {
private final EnumMap<GeolocationProvider, GeolocationService> map;
@Autowired
public GeoLocationProviderContext(Set<GeolocationService> geolocationServiceSet) {
map = new EnumMap<>(GeolocationProvider.class);
geolocationServiceSet.forEach(service -> map.put(service.getGeoProvider(), service));
}
public GeolocationService getService(GeolocationProvider provider) {
return map.get(provider);
}
}
@RestController
public class GeolocationController {
@Autowired
GeoLocationProviderContext geoLocationProviderContext;
@GetMapping(value = "/coordinates/for/city/{cityname}/{provider}")
public ResponseEntity<Result> getLocation(@PathParam(value = "cityname") String city,
@PathParam(value = "provider")GeolocationProvider provider) {
GeolocationService service = geoLocationProviderContext.getService(provider);
Result result = geolocationService.getLatLongByCity(city);
return ResponseEntity.ok().body(result);
}
}