열거형에 콩 주입
보고서를 위한 데이터를 준비하는 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
등록된 모든 정보를 추적하는 필드WidgetFactor
ies. as a.postConstruct
operation 우리는 열거와 관련된 공장의 지도를 만듭니다.
이제 고객들은 환자들에게WidgetService
class 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();
}
}
Enum
s는 정적이기 때문에 정적인 맥락에서 콩에 접근할 수 있는 방법을 찾아야 합니다.
이름이 붙은 클래스를 만들 수 있습니다.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 |