2012-01-06 5 views
2

Когда я определил компонент «MethodInvokingFactory» с «scope = step», у меня появилась ошибка, что тип компонента не может быть определен. Он отлично работал, когда я заменил «scope = step» на «lazy-init = true». По моим сведениям, оба используются для позднего связывания фасоли, за исключением этой разницы. Существуют ли другие различия между этими двумя способами? Также верно ли мое использование?В весеннем пакетном режиме в чем разница между «lazy-init = true» и «scope = step»?

Пожалуйста, дайте мне знать ваши мысли об этом.

ответ

3

Чтобы ответить на ваш вопрос с точки зрения низкого уровня:

lazy-init="true" означает, что фасоль не будут создаваться, когда создается контекст, но будет создан, когда его называют, например, другим фасолью. Я думаю, это ясно, также из комментария @AravindA.

Скошенные бобы работают по-разному. Когда контекст создается, этот компонент переносится в дополнительный прокси-объект (по умолчанию созданный CGLIB), который передается компоненту, который ссылается на него (этот прокси по умолчанию является singleton, например, shared). Таким образом, каждый раз, когда метод вызывается в прокси-сервере во время выполнения, Spring пересекает вызов, просит фабрику вернуть экземпляр компонента и вызывает метод для этого компонента. Завод, в свою очередь, может искать «реальный» экземпляр компонента, например. в запросе HTTP (область запроса) или сеансе HTTP (область «сеанс») и/или при необходимости создать новый экземпляр. Поздняя инстанцировка позволяет инициализировать бонусный объект со значениями «времени выполнения» (объема), например. значения из HTTP-запроса/сеанса, которые, очевидно, не определены при создании контекста. В частности, «шаговые» компоненты с привязкой привязаны к потоку локально (помните, что шаги выполняются параллельно для разбиения). Таким образом, скошенные бобы разрываются, когда вы вызываете метод на них. Наконец, можно легко разбить эту изящную «идеологию весны», вызывая любой метод на предметном bean-компоненте сразу после того, как он настроен на другой компонент (например, в сеттере) :)

+0

Спасибо @dma_k. Теперь это имеет смысл. Но когда я использовал «scope = step» на всех упомянутых компонентах, я столкнулся с этой ошибкой. ** Ошибка Msg ** - 'Невозможно преобразовать значение типа [$ Proxy5, реализующее org.springframework.aop.scope.ScopedObject, org.springframework.aop.framework.AopInfrastructureBean, org.springframework.aop.SpringProxy, org.springframework.aop .framework.Advised] до требуемого типа [XXX.XXX.MyClass]: не найдено подходящих редакторов или стратегии конверсии. «Не могли бы вы рассказать мне, почему это происходит? Разве Spring не должна возвращать компонент автоматически, когда передается фасоль? –

+0

Я думаю, я знаю, в чем проблема: поскольку ваш bean-компонент завернут, он не соответствует запрошенному классу. Итак: либо выполняйте аутоавтоматизацию по типу, но ** используйте интерфейсы ** (интерфейсы автоматически распространяются на прокси) ('@Autowire MyInterface bean') или используют autowiring по имени (' @Resource («myBean») bean'). Если это автоустановка конструктора, которая вызвала проблему, то, по-моему, единственным вариантом является интерфейс. –

+0

@ dma_k Вместо autowiring (с помощью Google) я добавил этот компонент и, на удивление, это сработало как шарм. '<свойство name =" proxyTargetClass "value =" true "/>'. Я больше не получаю никаких ошибок при преобразовании прокси-сервера, как указано выше. Тем не менее я не вижу, как это решает проблему. Не могли бы вы бросить какой-то свет? –

1
 One thing to understand about lazy-initialization is that even though a bean 
     definition may be marked up as being lazy-initialized, if the lazy-initialized  
     bean is the dependency of a singleton bean that is not lazy-initialized, when the 
     ApplicationContext is eagerly pre-instantiating the singleton, it will have to 
     satisfy all of the singletons dependencies, one of which will be the 
     lazy-initialized bean! 

     Using a scope of Step is required in order to use late binding since the bean 
     cannot actually be instantiated until the Step starts, which allows the 
     attributes to be found. Because it is not part of the Spring container by 
     default, the scope must be added explicitly, either by using the batch namespace 
     or by including a bean definition explicitly for the StepScope (but not both): 

     <bean class="org.springframework.batch.core.scope.StepScope" /> 

Читать here и here для получения дополнительной информации

Область = «шаг» не имеет ничего общего с инициализацией ленивых. Это используется для позднего связывания параметров внутри «Step».

+0

Спасибо, что нашли время в ответе. Но, мой вопрос заключается в том, что ** различия между этими двумя способами достижения ленивого переплета **. –

+0

@ Java Bean, scope = "step" используется в контексте партии Spring выше для привязки ресурсов в пределах шага. Шаг - это объект домена, который инкапсулирует независимую последовательную фазу пакетного задания. По умолчанию это не часть весеннего контейнера, тогда как lazy-init. В весенней партии любой бит, который использует позднюю привязку, должен быть объявлен с помощью scope = «step». –

+0

Я бы сказал, что «любые bean-компоненты, которые ссылаются на переменные по конкретному шагу (например, показанные @MichaelLange), должны быть в шаге». –

1

область действия шага специально предназначена для latebinding of job/step attributes и не предназначена для позднего связывания фасолей, что означает, что контекст фасоли/фабрика будет улучшать шаговые кубики и искать атрибуты для установки, например.

value="#{jobParameters[input.file.name]} 
+0

@ Micheal Lange Хорошо, если я использую область шагов для достижения ленивой привязки bean-компонентов (вместо атрибутов, то есть когда все атрибуты уже установлены)? Или это вызовет другие проблемы? –

+0

ленивое связывание фасоли отличается от ленивого связывания атрибутов весенней партией, пожалуйста, обратитесь к http://stackoverflow.com/a/8761244/62201, я бы не использовал StepScope, если ленивое связывание бобов - единственное требование –

+0

спасибо за вашу помощь @Micheal Lange. Если бы вы могли сказать мне, почему бы не использовать stepScope для ленивой привязки.:) –