Используя Spring МОК для установки перечислимых значений

использовать regexp_replace

with All_Cust_Data(Cust_Desc) as
(
 select 'John, Doe, Client ID 7, Region Code, 4....' from dual
)
select regexp_replace(Cust_Desc,'(.*),.\Region Code.*','\1') as "Result String"
  from All_Cust_Data;

    Result String
-----------------------
John, Doe, Client ID 7

Rextester Demo kbd>

27
задан Peter O. 10 January 2013 в 21:35
поделиться

9 ответов

Вы означаете настраивать enum самостоятельно?

Я не думаю, что это возможно. Вы не можете инстанцировать перечислений, потому что у них есть a static природа. Таким образом, я думаю, что Spring МОК не может создать enums также.

С другой стороны, если необходимо установить, инициализируют что-то с a enum проверьте Spring глава МОК. (поиск перечисления) существует простой пример, который можно использовать.

15
ответ дан bruno conde 28 November 2019 в 05:17
поделиться

Я не думаю, что это может быть сделано от Spring ApplicationContext конфигурация. Но, сделайте Вас, действительно нуждаются в сделанном Spring, или можете Вы соглашаться на простое использование воплощения ResourceBundle; как это:

public enum Car
{
    NANO,
    MERCEDES,
    FERRARI;

    public final String cost;
    public final String madeIn;

    Car()
    {
            this.cost = BUNDLE.getString("Car." + name() + ".cost");
            this.madeIn = BUNDLE.getString("Car." + name() + ".madeIn");
    }

    private static final ResourceBundle BUNDLE = ResourceBundle.getBundle(...);

}

В файле свойств, один для каждой определенной локали, вводят ключи, описывающие возможные внутренние перечислимые значения:

Car.NANO.cost=Very cheap
Car.NANO.madeIn=India
Car.MERCEDES.cost=Expensive
...

Единственный недостаток этого подхода должен повторить название перечислимых полей (стоимость, madeIn) в коде Java как строки.Править: И зато, можно сложить все свойства всех перечислений в один файл свойств на язык/локаль.

11
ответ дан javashlook 28 November 2019 в 05:17
поделиться

Почему бы не обеспечить метод set (или аргумент конструктора), который берет Строку и просто называет Enum.valueOf (Представляют s в виде строки) преобразовать от Строки до перечисления. Обратите внимание, что исключение будет выдано, если это перестанет работать, и Ваша инициализация Spring прыгнет с парашютом.

3
ответ дан Brian Agnew 28 November 2019 в 05:17
поделиться

Что необходимо настроить? Стоимость создается, когда класс загружается, и поскольку это - перечисление, никакая другая стоимость не может быть создана (если Вы не добавляете их к источнику и перекомпилировали).

В этом суть перечисления, чтобы смочь дать пределу тип явному диапазону постоянных, неизменных значений. Теперь, где угодно в Вашем коде, можно обратиться к Автомобилю типа, или его значениям, Автомобилю. НАНО, Автомобиль. MERCEDES, и т.д.

Если с другой стороны, у Вас есть множество значений, которое не является явным диапазоном, и Вы хотите смочь создать произвольные объекты этого типа, Вы использовали бы тот же ctor в качестве в Вашем сообщении, но в качестве постоянного клиента, не класса Enum. Затем Spring обеспечивает различные классы помощника, чтобы считать значения из некоторого источника (XML-файл, файл конфигурации, безотносительно) и создать Списки того типа.

1
ответ дан tpdi 28 November 2019 в 05:17
поделиться
<bean id="car" class="Foo">
    <property name="carString" value="NANO" />
</bean>

И затем в Вашем классе Foo, у Вас был бы этот метод set:

public void setCar(String carString) {
    this.carString = Car.valueOf(carString);
}
1
ответ дан Greg Noe 28 November 2019 в 05:17
поделиться

Хорошо, это немного сложно, но можно найти способ интегрировать его. Перечисления не предназначены для изменения во времени выполнения, таким образом, это - отражательный взлом. Извините у меня нет части реализации Spring, но Вы могли просто создать боб для взятия в классе Enum или объекте и другом поле, которое будет новым значением или значениями.

Constructor con = MyEnum.class.getDeclaredConstructors()[0];
Method[] methods = con.getClass().getDeclaredMethods();
for (Method m : methods) {
  if (m.getName().equals("acquireConstructorAccessor")) {
    m.setAccessible(true);
    m.invoke(con, new Object[0]);
  }
}
Field[] fields = con.getClass().getDeclaredFields();
Object ca = null;
for (Field f : fields) {
  if (f.getName().equals("constructorAccessor")) {
    f.setAccessible(true);
    ca = f.get(con);
  }
}
Method m = ca.getClass().getMethod(
  "newInstance", new Class[] { Object[].class });
m.setAccessible(true);
MyEnum v = (MyEnum) m.invoke(ca, new Object[] { 
  new Object[] { "MY_NEW_ENUM_VALUE", Integer.MAX_VALUE } });
  System.out.println(v.getClass() + ":" + v.name() + ":" + v.ordinal());

Это взято от этого сайта.

0
ответ дан Greg Noe 28 November 2019 в 05:17
поделиться

Вот решение, к которому я пришел (благодаря Javashlook, ответ которого поставил меня на правильный путь). Это работает, но, скорее всего, это не способ промышленного уровня.

Но лучше, чем тысяча слов, вот код, я позволю вам судить сами.

Давайте посмотрим на пересмотрено Car enum:

public enum Car {
    NANO(CarEnumerationInitializer.getNANO()), MERCEDES(
            CarEnumerationInitializer.getMERCEDES()), FERRARI(
            CarEnumerationInitializer.getFERRARI());

    public final String cost;
    public final String madeIn;

    Car(ICarProperties properties) {
        this.cost = properties.getCost();
        this.madeIn = properties.getMadeIn();
    }
}

И вот «отвесные» классы:

//Car's properties placeholder interface ...
public interface ICarProperties {
    public String getMadeIn();
    public String getCost();
}
//... and its implementation
public class CarProperties implements ICarProperties {
    public final String cost;
    public final String madeIn;

    public CarProperties(String cost, String madeIn) {
        this.cost = cost;
        this.madeIn = madeIn;
    }
    @Override
    public String getCost() {
        return this.cost;
    }
    @Override
    public String getMadeIn() {
        return this.madeIn;
    }
}

//Singleton that will be provide Car's properties, that will be defined at applicationContext loading.
public final class CarEnumerationInitializer {
    private static CarEnumerationInitializer INSTANCE;
    private static ICarProperties NANO;
    private static ICarProperties MERCEDES;
    private static ICarProperties FERRARI;

    private CarEnumerationInitializer(ICarProperties nano,
            ICarProperties mercedes, ICarProperties ferrari) {
        CarEnumerationInitializer.NANO = nano;
        CarEnumerationInitializer.MERCEDES = mercedes;
        CarEnumerationInitializer.FERRARI = ferrari;
    }

    public static void forbidInvocationOnUnsetInitializer() {
        if (CarEnumerationInitializer.INSTANCE == null) {
            throw new IllegalStateException(CarEnumerationInitializer.class
                    .getName()
                    + " unset.");
        }
    }

    public static CarEnumerationInitializer build(CarProperties nano,
            CarProperties mercedes, CarProperties ferrari) {
        if (CarEnumerationInitializer.INSTANCE == null) {
            CarEnumerationInitializer.INSTANCE = new CarEnumerationInitializer(
                    nano, mercedes, ferrari);
        }
        return CarEnumerationInitializer.INSTANCE;
    }

    public static ICarProperties getNANO() {
            forbidInvocationOnUnsetInitializer();
        return NANO;
    }

    public static ICarProperties getMERCEDES() {
            forbidInvocationOnUnsetInitializer();
        return MERCEDES;
    }

    public static ICarProperties getFERRARI() {
            forbidInvocationOnUnsetInitializer();
        return FERRARI;
    }
}

Наконец, определение applicationContext:

<?xml version="1.0" encoding="UTF-8"?>
<beans>
    <bean id="nano" class="be.vinkolat.poc.core.car.CarProperties">
        <constructor-arg type="java.lang.String" value="Cheap"></constructor-arg>
        <constructor-arg type="java.lang.String" value="India"></constructor-arg>
    </bean>
    <bean id="mercedes"
        class="be.vinkolat.poc.core.car.CarProperties">
        <constructor-arg type="java.lang.String" value="Expensive"></constructor-arg>
        <constructor-arg type="java.lang.String" value="Germany"></constructor-arg>
    </bean>
    <bean id="ferrari" class="be.vinkolat.poc.core.car.CarProperties">
        <constructor-arg type="java.lang.String"
            value="Very Expensive">
        </constructor-arg>
        <constructor-arg type="java.lang.String" value="Italy"></constructor-arg>
    </bean>
    <bean id="carInitializer"
        class="be.vinkolat.poc.core.car.CarEnumerationInitializer"
        factory-method="build" lazy-init="false">
        <constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
            ref="nano" />
        <constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
            ref="mercedes" />
        <constructor-arg type="be.vinkolat.poc.core.car.CarProperties"
            ref="ferrari" />
    </bean>
</beans>

Это работает, но есть один существенный недостаток: CarEnumerationInitializer НЕОБХОДИМО, чтобы был создан экземпляр ДО ТОГО, как будет сделана ссылка на перечисление Car , в противном случае CarProperties будут иметь значение null, что означает, что свойства Car не могут быть установлены при загрузке Car (отсюда и IllegalStateException брошен, по крайней мере, чтобы он падал предсказуемым и задокументированным способом). carInitializer Свойство bean-компонента lazy-init установлено в явное ложное , чтобы подчеркнуть необходимость его загрузки как можно скорее. Я бы сказал, что это может быть полезно в простом приложении, в котором можно легко угадать, где будет сделан первый вызов Car . Для более крупного, вероятно, это будет такой беспорядок, что я не рекомендовал вам его использовать.

Надеюсь, эта помощь, комментарии и голосование (вверх и вниз) очень приветствуются :) Я подожду несколько дней чтобы сделать этот ответ принятым, чтобы вы могли реагировать.

0
ответ дан Olivier 28 November 2019 в 05:17
поделиться

Я столкнулся с той же проблемой, когда я работал для локализации моей перечислимой маркировки в различных локалях.

Перечислимый Код:

public enum Type {
   SINGLE("type.single_entry"),
   MULTIPLE("type.multiple_entry"),
   String label;

   Type(String label) {
     this.label = label;
   }

   public String getLabel() {
     String translatedString = I18NTranslator.getI18NValue(getLocale(), label);
     return StringUtils.isEmpty(translatedString) ? label : translatedString;
   }
}

Мой класс I18NTranslator, которые в основном загружают источник сообщения для получения локализованного содержания. I18Ntransalator класс зависит от springContext, если Вы не пишете, что могли бы столкнуться со специфической ошибкой. Некоторое время могло бы стоять перед зависимостью, связанной который исключение нулевого указателя причин. Я приложил много усилий решить этот вопрос.

@Component
@DependsOn({"springContext"})
public class I18NTranslator {

    private static MessageSource i18nMessageSource;

    public static String getI18NValue(Locale locale, String key) {
        if (i18nMessageSource != null)
            return i18nMessageSource.getMessage(key, null, locale);
        return key;
    }

    @PostConstruct
    public void initialize() {
        i18nMessageSource = SpringContext.getBean("i18nMessageSource", MessageSource.class);
    }
}

Мы должны установить пружинный контекст

@Component
@Slf4j
public class SpringContext implements ApplicationContextAware {

    private static ApplicationContext context;

    public static <T extends Object> T getBean(Class<T> beanClass) {
        return context.getBean(beanClass);
    }

    public static <T extends Object> T getBean(String beanClassName, Class<T> beanClass) {
        return context.getBean(beanClassName, beanClass);
    }

    @Override
    public void setApplicationContext(ApplicationContext context) throws BeansException {
        SpringContext.context = context;
    }
}

Теперь, пора определить боб для I18NMessageSource.

@Configuration
public class LocaleConfiguration implements WebMvcConfigurer {

    @Bean(name = "i18nMessageSource")
    public MessageSource getMessageResource() {
        ReloadableResourceBundleMessageSource messageResource = new ReloadableResourceBundleMessageSource();
        messageResource.setBasename("classpath:i18n/messages");
        messageResource.setCacheSeconds(3600);
        messageResource.setDefaultEncoding("UTF-8");
        return messageResource;
    }

    @Bean(name = "localeResolver")
    public LocaleResolver getLocaleResolver() {
        return new UrlLocaleResolver();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //UrlLocalInterceptor is custom locale resolver based on header paramter.
        UrlLocaleInterceptor localeInterceptor = new UrlLocaleInterceptor();
        registry.addInterceptor(localeInterceptor);
    }
}

пз: если Вам нужен пользовательский код перехватчика, я могу совместно использовать в комментарии. Определяет все файлы локальных свойств внутри resources/i18n папка с префиксом сообщений как messages_en.properties для английского языка и messages_fr.properties fro французский язык.

0
ответ дан 28 November 2019 в 05:17
поделиться

Попытка изменить Enum довольно глупая и полностью противоречит целям их дизайна. Перечисление по определению представляет собой отдельное значение в группе. Если вам когда-нибудь понадобится больше / меньше значений, вам нужно будет обновить источник. Хотя вы можете изменить состояние перечислений, добавив сеттеры (в конце концов, это просто объекты), вы взламываете систему.

1
ответ дан 28 November 2019 в 05:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: