Передающие свойства к контексту Spring

Давайте начнем с циклической зависимости.

trait A {
  selfA: B =>
  def fa: Int }

trait B {
  selfB: A =>
  def fb: String }

Тем не менее, модульность этого решения не так велика, как может показаться на первый взгляд, потому что вы можете переопределить собственные типы следующим образом:

trait A1 extends A {
  selfA1: B =>
  override def fb = "B's String" }
trait B1 extends B {
  selfB1: A =>
  override def fa = "A's String" }
val myObj = new A1 with B1

Хотя, если вы переопределите член При самостоятельном вводе вы теряете доступ к исходному члену, доступ к которому по-прежнему возможен через супер, используя наследование. Итак, что действительно выигрывает от использования наследования:

trait AB {
  def fa: String
  def fb: String }
trait A1 extends AB
{ override def fa = "A's String" }        
trait B1 extends AB
{ override def fb = "B's String" }    
val myObj = new A1 with B1

Теперь я не могу утверждать, что понимаю все тонкости шаблона торта, но мне кажется, что основной метод обеспечения модульности - это скорее композиция чем наследование или самопознание.

Версия наследования короче, но главная причина, по которой я предпочитаю наследование по сравнению с типами self, заключается в том, что мне гораздо сложнее получить правильный порядок инициализации с типами self. Однако есть некоторые вещи, которые вы можете делать с типами себя, которые вы не можете делать с наследованием. Сами типы могут использовать тип, в то время как наследование требует черты или класса, как в:

trait Outer
{ type T1 }     
trait S1
{ selfS1: Outer#T1 => } //Not possible with inheritance.

Вы даже можете сделать:

trait TypeBuster
{ this: Int with String => }

Хотя вы никогда не сможете создать его экземпляр , Я не вижу какой-либо абсолютной причины неспособности наследовать от типа, но я, конечно, чувствую, что было бы полезно иметь классы и свойства конструктора путей, поскольку у нас есть свойства / классы конструктора типов. Как, к сожалению,

trait InnerA extends Outer#Inner //Doesn't compile

У нас есть это:

trait Outer
{ trait Inner }
trait OuterA extends Outer
{ trait InnerA extends Inner }
trait OuterB extends Outer
{ trait InnerB extends Inner }
trait OuterFinal extends OuterA with OuterB
{ val myV = new InnerA with InnerB }

Или это:

  trait Outer
  { trait Inner }     
  trait InnerA
  {this: Outer#Inner =>}
  trait InnerB
  {this: Outer#Inner =>}
  trait OuterFinal extends Outer
  { val myVal = new InnerA with InnerB with Inner }

Еще один момент, на который следует обратить особое внимание, заключается в том, что черты могут расширять классы. Спасибо Дэвиду Маклверу за указание на это. Вот пример из моего собственного кода:

class ScnBase extends Frame
abstract class ScnVista[GT <: GeomBase[_ <: TypesD]](geomRI: GT) extends ScnBase with DescripHolder[GT] )
{ val geomR = geomRI }    
trait EditScn[GT <: GeomBase[_ <: ScenTypes]] extends ScnVista[GT]
trait ScnVistaCyl[GT <: GeomBase[_ <: ScenTypes]] extends ScnVista[GT]

ScnBase наследуется от класса фрейма Swing , так что он может быть использован как собственный тип, а затем смешан в конце ( при создании экземпляра). Однако, val geomR необходимо инициализировать, прежде чем он будет использован для наследования черт. Таким образом, нам нужен класс для обеспечения предварительной инициализации geomR. Класс ScnVista может затем наследоваться множеством ортогональных признаков, которые сами могут наследоваться. Использование параметров нескольких типов (обобщений) предлагает альтернативную форму модульности.

8
задан Alex Abdugafarov 25 October 2011 в 07:18
поделиться

5 ответов

Обновление :

На основе обновления вопроса я предлагаю:

  1. Создать ] Bean-компонент ServiceResolver , который обрабатывает все, что вам нужно, на основе ввода клиента;
  2. объявлять этот bean-компонент как зависимость от соответствующих служб;
  3. во время выполнения, вы можете обновлять / использовать этот bean-компонент по своему усмотрению.

Затем ServiceResolver может либо в init-методе , либо при каждом вызове определять значения, возвращаемые клиенту , основанный, например, на поиске JNDI или переменных окружения.

Но перед этим вы можете взглянуть на доступные параметры конфигурации . Вы можете либо:

  • добавить файлы свойств, которые не должны присутствовать во время компиляции;
  • искать значения из JNDI;
  • получать значения из System.properties.

Если вам нужно для поиска свойств из настраиваемого местоположения, посмотрите org.springframework.beans.factory.config.BeanFactoryPostProcessor и как реализован org.springframework.beans.factory.config.PropertyPlaceholderConfigurer .

1
ответ дан 5 December 2019 в 10:04
поделиться

Создайте экземпляр RmiProxyFactoryBean и настройте свойство serviceUrl прямо в коде:

String serverHost = "www.example.com";

RmiProxyFactoryBean factory = new RmiProxyFactoryBean();
factory.setServiceUrl("rmi://" + serverHost + ":80/MyService");
factory.setServiceInterface(MyService.class);
try {
    factory.afterPropertiesSet();
} catch (Exception e) {
    throw new RuntimeException(
            "Problem initializing myService factory", e);
}
MyService myService = (MyService) factory.getObject();
0
ответ дан 5 December 2019 в 10:04
поделиться

Мое существующее решение включает определение нового MapAwareApplicationContext, который принимает Map в качестве дополнительного аргумента конструктора.

public MapAwareApplicationContext(final URL[] configURLs,
    final String[] newConfigLocations,
    final Map<String, String> additionalProperties) {
    super(null);

    //standard constructor content here

    this.map = new HashMap<String, String>(additionalProperties);

    refresh();
}

Он переопределяет postProcessBeanFactory () для добавления в MapAwareProcessor:

protected void postProcessBeanFactory(
    final ConfigurableListableBeanFactory beanFactory) {
    beanFactory.addBeanPostProcessor(new MapAwareProcessor(this.map));
    beanFactory.ignoreDependencyInterface(MapAware.class);
}

MapAwareProcessor реализует postProcessBeforeInitialization () чтобы вставить карту в любой тип, реализующий интерфейс MapAware:

public Object postProcessBeforeInitialization(final Object bean, 
        final String beanName) {
    if (this.map != null && bean instanceof MapAware) {
        ((MapAware) bean).setMap(this.map);
    }

    return bean;
}

Затем я добавляю новый компонент в свою конфигурацию, чтобы объявить MapAwarePropertyPlaceholderConfigurer:

<bean id="propertyConfigurer"
  class="com.hsbc.r2ds.spring.MapAwarePropertyPlaceholderConfigurer"/>

Конфигуратор реализует MapAware, поэтому он будет внедрен вместе с картой, как указано выше. Затем он реализует resolvePlaceholder () для разрешения свойств из карты или делегирует родительскому конфигуратору:

protected String resolvePlaceholder(final String placeholder, 
        final Properties props, final int systemPropertiesMode) {
    String propVal = null;
    if (this.map != null) {
        propVal = this.map.get(placeholder);
    }
    if (propVal == null) {
        propVal = super.resolvePlaceholder(placeholder, props);
    }
    return propVal;
}
2
ответ дан 5 December 2019 в 10:04
поделиться

PropertyPlaceholderConfigurer может получать свойства из файла, это правда, но если он не может их найти, он возвращается к использованию системных свойств. Это звучит как жизнеспособный вариант для вашего клиентского приложения, просто передайте системное свойство с помощью -D при запуске клиента.

Из javadoc

Конфигуратор также проверит против системные свойства (например, "user.dir"), если он не может разрешить заполнитель с любое из указанных свойств. это можно настроить через "systemPropertiesMode".

1
ответ дан 5 December 2019 в 10:04
поделиться

See http://forum.springsource.org/showthread.php?t=71815

TestClass.java

package com.spring.ioc;

публичный класс TestClass {

 Сначала частная Стринг;
 частная Строка вторая;

 public String getFirst() {
 Возвращайся первым;
 }

 public void setFirst(Сначала строка) {
 это. Первый = первый;
 }

 публичная Строка getSecond() {
 возвращайся через секунду;
 }

 public void setSecond(String second) {
 это. Секунда = секунда;
 }
}

SpringStart.java

 package com.spring;

импорт java.util.Properties;

импорт com.spring.ioc.TestClass;
импорт org.springframework.context.support.ClassPathXmlApplicationContext;
импорт org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;

публичный класс SpringStart {
 public static void main(String[] args) выбрасывает исключение {{
 PropertyPlaceholderConfigurer configurer = new PropertyPlaceholderConfigurer();
 Свойства properties = new Properties();
 properties.setProperty("first.prop", "first value");
 properties.setProperty("second.prop", "второе значение");
 configurer.setProperties(properties);

 ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
 context.addBeanFactoryPostProcessor(configurer);

 context.setConfigLocation("spring-config.xml");
 context.refresh();

 TestClass testClass = (TestClass)context.getBean("testBean");
 System.out.println(testClass.getFirst());
 System.out.println(testClass.getSecond());
 }
}

spring-config.xml


<бобы xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:схемаЛокация="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

 
 <имя собственности="first" value="${first.prop}"/>
 <имя свойства="второе" значение="${секунда.prop}"/>
 

Выход:

 первое значение.
второе значение
13
ответ дан 5 December 2019 в 10:04
поделиться
Другие вопросы по тегам:

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