2015-05-28 2 views
0

Я пытаюсь написать Spring FactoryBean, который будет создавать список объектов Request. Количество запросов и значений, которые входят в них, настраиваются во время выполнения, поэтому я хочу использовать для них свойства.Может ли Spring FactoryBean получить доступ ко всем свойствам в контексте?

Каждый запрос состоит из пары значений идентификатора, поэтому мне нужно каким-то образом предоставить Factory Bean настраиваемый список этих пар ID (назовите их A и B на данный момент).

То, что я получил до сих пор использовать свойство, которое выглядит примерно так:

requests=1/2,3/4,5/6 

, который затем определяет три запроса, один с = 1 и B = 2, один с А = 3 и B = 4 и один с A = 5 и B = 6.

Это, очевидно, немного противно настраивать и, скорее, подвержено ошибкам. Что было бы гораздо приятнее было бы сделать что-то со значениями разделить на многие свойства, так что выше, может быть что-то вроде:

requests.1.A=1 
requests.1.B=2 

requests.2.A=3 
requests.2.B=4 

requests.3.A=5 
requests.3.B=6 

Который только делает его немного более очевидным, что происходит.

Однако я не могу найти способ настроить свой FactoryBean для доступа к всем доступным свойствам, а не только специально указанному свойству, которое передается из контекста.

Я что-то упустил? Или - еще лучше - есть ли лучший способ сделать такую ​​конфигурацию, которая легче поддерживается и поддерживается?

+0

Зачем придумывать свои собственные? Spring может использовать файл свойств (рядом с xml или java) для создания beans, ['PropertyBeanDefinitionReader'] (http: //docs.spring.И.О./весна/Docs/ток/Javadoc-апи/орг/springframework/бобы/завод/поддержка/PropertiesBeanDefinitionReader.html). Просто используйте это, создайте файл, загрузите его и хорошо сделайте. –

+0

Я не знал, что даже существовал. Тем не менее, это конфигурация клиента, а не мы, и есть другая конфигурация, которую они также должны предоставить, но у меня будет игра и посмотреть, работает ли она :) – Graham

+0

Итак, и почему это важно? В вашей фабричной фасоли загрузите конфигурацию, получите все бобы из 'BeanFactory' и presto. Судя по сообщению, вы определяете формат конфигурации. Пока вы указываете его, вы можете использовать все, что хотите. Если файл находится, не имеет значения, если вы можете создать «Ресурс», он будет работать. И с ним вы можете установить все свойства (или аргументы конструктора). –

ответ

1

Вы можете ввести bean-компонент Environment в свой экземпляр FactoryBean, он предоставляется контекстом, и вам не нужно его настраивать. Я не уверен, как вы настраиваете свои компоненты, но я всегда поддерживаю конфигурацию Java. Таким образом, этот пример будет использовать конфигурацию Java.

@Configuration 
class FactoryBeanConfig { 
    @Bean 
    public FactoryBean(final Environment env) { 
     return new MyFactoryBean(env); 
    } 
} 

Экземпляр среда даст вам доступ ко всем свойствам, потому что это PropertyResolver Вы можете программно цикл по свойствам

int x = 1; 
while(true) { 
    env.getRequiredProperty("requests." + x + ".A") 
    env.getRequiredProperty("requests." + x + ".B") 
} 
+0

Ooh - Я не знал, что вы могли бы добавить окружающую среду. Это выглядит очень обнадеживающим :) Я использую XML-конфигурацию, но я полагаю, что это работает точно так же? – Graham

+2

Если вы хотите, чтобы среда просто добавила поле типа «Среда» и положила на него '@ Autowired'. Вам не нужно вводить его так: –

+0

@ M.Deinum вы правы. Это то, как мне нравится это делать. Но есть несколько способов получить введенную среду – Leon

0

Если вы хотите использовать, чтобы создавать экземпляры конкретного bean Я бы предложил использовать PropertiesBeanDefinitionReader. Укажите 2 файла свойств для загрузки (один из которых хорошо известен по умолчанию) и один для добавления компонентов.

core-request.properties

request.(class)=com.company.pkg.Request 

requests.properties

requests1.A=1 
requests1.B=2 

requests2.A=3 
requests2.B=4 

requests3.A=5 
requests3.B=6 

Теперь вы можете использовать свой FactoryBean построить BeanFactory и получить все бобы и подвергать их как список.

public class YourFactoryBean implements FactoryBean<List<Request>> { 

    @Autowired 
    private ResourceLoader rl; 

    public Object getObject() { 
     DefaultListableBeanFactory beanRegistry = new DefaultListableBeanFactory; 
     PropertiesBeanDefinitionLoader loader = new PropertiesBeanDefinitionLoader(beanRegistry); 
     Resource core = rl.getResource(core-location); 
     Resource requests = rl.getResource(requests-location); 
     loader.loadBeanDefinitions(core); 
     loader.setDefaultParentBean("request"); 
     loader.loadBeanDefinitions(requests); 
     return beanRegistry.getBeansOfType(Request.class).values(); 
    } 

} 

Нечто подобное.

Смежные вопросы