Тип, который выводится вашим компилятором до назначения для X
, - Integer & CharSequence
. Этот тип чувствует странным, потому что Integer
является окончательным, но он является вполне допустимым типом в Java. Затем он переключается на Integer
, что совершенно нормально.
Существует только одно возможное значение для типа Integer & CharSequence
: null
. С помощью следующей реализации:
X getCharSequence() {
return null;
}
Следующее назначение будет работать:
Integer x = getCharSequence();
Из-за этого возможного значения нет причин, по которым назначение должно быть неправильным, даже если оно очевидно бесполезно. Предупреждение было бы полезно.
. На самом деле, я недавно написал блог об этом API-шаблоне API . Вы должны (почти) никогда не разрабатывать общий метод для возврата произвольных типов, потому что вы можете (почти) никогда не гарантировать, что выводимый тип будет доставлен. Исключением являются такие методы, как Collections.emptyList()
, в случае которых пустота списка (и стирание родового типа) является причиной того, что любой вывод для
будет работать:
public static final List emptyList() {
return (List) EMPTY_LIST;
}
Я думаю, что вам нужно
public enum MyEnum {
ONE,TWO,THREE;
}
Autowire enum как обычно
@Configurable
public class MySpringConfiguredClass {
@Autowired
@Qualifier("mine")
private MyEnum myEnum;
}
Вот трюк, используйте factory-method = "valueOf" и также убедитесь, что lazy-init = "false"
, поэтому контейнер создает bean upfront
<bean id="mine" class="foo.bar.MyEnum" factory-method="valueOf" lazy-init="false">
<constructor-arg value="ONE" />
</bean>
, и все готово!
будет трудно контролировать, что весенний контейнер уже запущен и запущен во время создания перечисления (если у вас была переменная с этим типом в тестовом случае, ваш контейнер обычно не будет там, даже aspectj автоустановка там не поможет). я бы рекомендовал просто позволить службе dataprepare или что-то дать вам специфические параметры с помощью метода lookup с параметром enum.
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();
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);
}
}
[...]
}
Ответ на выходные работает, если вы меняете внутренний класс на статичный, чтобы весна его видна
Просто передайте его методу вручную
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 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"),
...
}