2014-11-19 2 views
2

Если я использую Spring, какой из этих двух методов является более правильным. Можно ли использовать оператор new(), даже если я использую dipendency injection ?.Can Я смешиваю оба? Я хотел бы получить некоторые разъяснения по этим понятиям. БлагодаряВесна: новый() оператор и автоподключен вместе

Первый метод:

@RequestMapping(method=RequestMethod.GET) 
public String create(Model model){ 
model.addAttribute(new User()); 
return "index"; 
} 

Второй метод:

@Autowired 
User user; 

@RequestMapping(method=RequestMethod.GET) 
public String create(Model model){ 
model.addAttribute(user); 
return "index"; 
} 

ответ

0

Если вы хотите, чтобы ваши бобы должны быть "управляемой" к весне (например, для использования с Dependency Injection или PropertySources или любой другие связанные с Spring функции), то вы НЕ создаете новые объекты самостоятельно. Вы объявляете их (через XML или JavaConfig) и позволяете Spring создавать и управлять ими.

Если фазе не нужно «управлять» весной, вы можете создать новый экземпляр, используя новый оператор.

В вашем случае этот конкретный объект - Пользователь - используется где-нибудь еще в коде? Он вводится в любой другой весенний боб? Или какой-либо другой весенний боб вводится в User? Как насчет любой другой весенней функциональности?

Если ответ на все эти вопросы «Нет», вы можете использовать первый метод (создать новый объект и вернуть его). Как только выполнение метода create() будет завершено, объект User, созданный там, исчезнет из области действия и будет отмечен для GC. Пользовательский объект, созданный в этом методе, в конечном итоге будет GC-ed.

+2

Ваше последнее предложение не является правильным. Это не «вне сферы действия». Объект все еще упоминается в объекте 'Model', на который ссылается' model'. В конечном итоге он будет перенесен в атрибуты «HttpServletRequest». Только когда цикл обработки запросов будет выполнен, и контейнер будет восстанавливать (или отбрасывает), 'ServletRequest' и' ServletResponse' будет объектом 'User' быть кандидатом для GC. –

+0

Вы правы. Я изменю свой комментарий. – Jigish

+0

Возможно, вы захотите поговорить об использовании второго метода с компонентом области прототипа. –

0

Вещи могут быть введены двумя способами в приложениях Spring MVC. И да, вы можете смешать инъекцию и создание, если поступаете правильно.

Компоненты, такие как контроллер в вашем примере, - это синглтоны, управляемые контекстом приложения. Если вы что-то им прикладываете, оно глобально, а не по запросу или сеансу! Таким образом, пользователь не подходит для инъекций, может быть каталог пользователя. Помните об этом, когда пишете многопоточное приложение!

Запросить связанные вещи могут быть введены в метод, такой как используемый язык, запрос, пользовательский пользователь может быть введен в качестве параметров, см. Полный список по адресу Spring MVC Documentation.

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

2

Использование инъекции зависимостей не означает, что использование оператора new автоматически запрещено во всем коде. Для разных требований применяются разные подходы.

Веб-приложение весной состоит из нескольких взаимодействующих компонентов, которые создаются каркасом и (кроме случаев переопределения области по умолчанию) являются одноточечными. Это означает, что они не должны сохранять какое-либо состояние, поскольку они распределены между всеми запросами (потоками). Другими словами, если вы autowire объект User (или любой другой атрибут модели), он создается при инициализации контекста приложения, и тот же экземпляр присваивается любому пользовательскому запросу. Это также означает, что если запрос изменяет объект, другие запросы также увидят эту модификацию. Излишне говорить, что это ошибочное поведение в многопоточных приложениях, потому что ваш объект User (или другой атрибут модели) принадлежит запросу, поэтому он должен иметь очень узкую область вызова метода или сеанса.

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

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

Таким образом, вы можете написать код выше, как

@RequestMapping(method=RequestMethod.GET) 
public String create(@ModelAttribute User user){  
return "index"; 
} 

Смотри также: Supported method argument types

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