열거형에 콩 주입
보고서를 위한 데이터를 준비하는 DataPrepareService가 있고 보고서 유형을 가진 Enum이 있으며 Enum에 ReportService를 주입하거나 Enum에서 ReportService에 액세스할 수 있어야 합니다.
나의 봉사합니다.
@Service
public class DataPrepareService {
// my service
}
나의 열거:
public enum ReportType {
REPORT_1("name", "filename"),
REPORT_2("name", "filename"),
REPORT_3("name", "filename")
public abstract Map<String, Object> getSpecificParams();
public Map<String, Object> getCommonParams(){
// some code that requires service
}
}
사용하려고 했습니다.
@Autowired
DataPrepareService dataPrepareService;
,하지만 그것은 작동하지 않았다.
서비스를 열거형에 주입하려면 어떻게 해야 합니까?
public enum ReportType {
REPORT_1("name", "filename"),
REPORT_2("name", "filename");
@Component
public static class ReportTypeServiceInjector {
@Autowired
private DataPrepareService dataPrepareService;
@PostConstruct
public void postConstruct() {
for (ReportType rt : EnumSet.allOf(ReportType.class))
rt.setDataPrepareService(dataPrepareService);
}
}
[...]
}
weeknes의 답변은 봄이 볼 수 있도록 내부 클래스를 정적으로 바꾸면 효과가 있습니다.
아마 이런 거겠지.
public enum ReportType {
@Component
public class ReportTypeServiceInjector {
@Autowired
private DataPrepareService dataPrepareService;
@PostConstruct
public void postConstruct() {
for (ReportType rt : EnumSet.allOf(ReportType.class))
rt.setDataPrepareService(dataPrepareService);
}
}
REPORT_1("name", "filename"),
REPORT_2("name", "filename"),
...
}
여러분이 탐색하고 싶은 또 다른 접근 방법이 있습니다.하지만 주사를 놓는 대신에bean안으로enum그것은 a와 관련이 있습니다.bean의 소리와 함께enum
열거형이 있다고 가정합니다.WidgetType그리고.Widget학급
public enum WidgetType {
FOO, BAR;
}
public class Widget {
WidgetType widgetType;
String message;
public Widget(WidgetType widgetType, String message) {
this.widgetType = widgetType;
this.message = message;
}
}
그리고 당신이 만들고 싶은 것은Widget공장을 사용하는 이 유형의 sBarFactory아니면FooFactory
public interface AbstractWidgetFactory {
Widget createWidget();
WidgetType factoryFor();
}
@Component
public class BarFactory implements AbstractWidgetFactory {
@Override
public Widget createWidget() {
return new Widget(BAR, "A Foo Widget");
}
@Override
public WidgetType factoryFor() {
return BAR;
}
}
@Component
public class FooFactory implements AbstractWidgetFactory {
@Override
public Widget createWidget() {
return new Widget(FOO, "A Foo Widget");
}
@Override
public WidgetType factoryFor() {
return FOO;
}
}
그WidgetService대부분의 작업이 이루어지는 곳입니다.여기 간단한 것이 있습니다.AutoWired등록된 모든 정보를 추적하는 필드WidgetFactories. as a.postConstructoperation 우리는 열거와 관련된 공장의 지도를 만듭니다.
이제 고객들은 환자들에게WidgetServiceclass and get factory를 지정된 열거형에 사용합니다.
@Service
public class WidgetService {
@Autowired
List<AbstractWidgetFactory> widgetFactories;
Map<WidgetType, AbstractWidgetFactory> factoryMap = new HashMap<>();
@PostConstruct
public void init() {
widgetFactories.forEach(w -> {
factoryMap.put(w.factoryFor(), w);
});
}
public Widget getWidgetOfType(WidgetType widgetType) {
return factoryMap.get(widgetType).createWidget();
}
}
Enums는 정적이기 때문에 정적인 맥락에서 콩에 접근할 수 있는 방법을 찾아야 합니다.
이름이 붙은 클래스를 만들 수 있습니다.ApplicationContextProvider를 구현하는ApplicationContextAware인터페이스.
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class ApplicationContextProvider implements ApplicationContextAware{
private static ApplicationContext appContext = null;
public static ApplicationContext getApplicationContext() {
return appContext;
}
public void setApplicationContext(ApplicationContext appContext) throws BeansException {
this.appContext = appContext;
}
}
그런 다음 응용프로그램 컨텍스트 파일을 추가합니다.
<bean id="applicationContextProvider" class="xxx.xxx.ApplicationContextProvider"></bean>
그 후에는 다음과 같은 정적인 방법으로 애플리케이션 컨텍스트에 액세스할 수 있습니다.
ApplicationContext appContext = ApplicationContextProvider.getApplicationContext();
열거형이 인스턴스화될 때 스프링 컨테이너가 이미 가동 중이고 실행 중이라는 것을 제어하는 것은 어렵습니다(테스트 케이스에 이 유형의 변수가 있는 경우 컨테이너는 일반적으로 존재하지 않습니다. aspectj autowireing이 여기에 도움이 되지 않음).저는 그냥 데이터 준비 서비스 같은 것이 enum-parameter가 있는 lookup-parameter와 함께 특정 method를 제공하도록 하는 것을 추천합니다.
당신에게 필요한 것은 이것이라고 생각합니다.
public enum MyEnum {
ONE,TWO,THREE;
}
일반적으로 열거형 자동 배선
@Configurable
public class MySpringConfiguredClass {
@Autowired
@Qualifier("mine")
private MyEnum myEnum;
}
다음은 factory-method="valueOf"를 사용하고 lazy-init=" false"를 확인하는 방법입니다.
그래서 용기는 콩을 만들어냅니다.
<bean id="mine" class="foo.bar.MyEnum" factory-method="valueOf" lazy-init="false">
<constructor-arg value="ONE" />
</bean>
그리고 당신은 끝!
수동으로 메소드에 전달하기만 하면 됩니다.
public enum ReportType {
REPORT_1("name", "filename"),
REPORT_2("name", "filename"),
REPORT_3("name", "filename")
public abstract Map<String, Object> getSpecificParams();
public Map<String, Object> getCommonParams(DataPrepareService dataPrepareService){
// some code that requires service
}
}
관리된 콩에서만 방법을 호출하는 한, 이 콩들에 주입하고 각 호출의 열거에 대한 참조를 전달할 수 있습니다.
이 솔루션을 사용할 수도 있습니다.
public enum ChartTypes {
AREA_CHART("Area Chart", XYAreaChart.class),
BAR_CHART("Bar Chart", XYBarChart.class),
private String name;
private String serviceName;
ChartTypes(String name, Class clazz) {
this.name = name;
this.serviceName = clazz.getSimpleName();
}
public String getServiceName() {
return serviceName;
}
@Override
public String toString() {
return name;
}
}
그리고 당신이 Enum의 콩을 필요로 하는 다른 클래스에서는:
ChartTypes plotType = ChartTypes.AreaChart
Object areaChartService = applicationContext.getBean(chartType.getServiceName());
언급URL : https://stackoverflow.com/questions/16318454/inject-bean-into-enum
'programing' 카테고리의 다른 글
| PowerShell에서 특정 UTC DateTime을 사용하여 DateTime 개체 생성 (0) | 2023.11.06 |
|---|---|
| ajax 요청 후 Chrome window.open(크롬 창)이 팝업처럼 작동합니다. (0) | 2023.11.06 |
| How to cast simple pointer to a multidimensional-array of fixed size? (0) | 2023.11.01 |
| 자바스크립트 HTML5 캔버스를 이용하여 N개의 포인트를 통해 매끄러운 곡선을 그리는 방법? (0) | 2023.11.01 |
| mysql (mariadb) 튜닝 및 성능 테스터 (0) | 2023.11.01 |