2012-04-29 6 views
0

Что касается простоты и правильности, то каков наилучший способ для ввода объектов одного и того же класса с различными областями?Как вводить объекты одного класса с разными областями?

В сервлете я хочу, чтобы объекты с одним и тем же классом обладали разными областями. По-прежнему не знаю, собираетесь ли использовать jsf.

  • Простота: изготовление Qualifier и метод изготовления для каждой области слишком много; создание интерфейса, два класса и добавление и альтернатива в beans.xml тоже слишком много; имеющий метод Address#isCurrent(), не имеет смысла.
  • Правильность: JSR299, 3.11 говорит: Использование @Named в качестве квалификатора точки впрыска не рекомендуется. Все еще не знаю почему.
    Хотя использование @Named в точке впрыска работает с @ApplicationScoped и @RequestScoped, но не с @SessionScoped. См. под названием snippet ниже.

Весной это очень легко:
Spring фрагмент

<bean id="currentAddress" class="xxx.Address" scope="session" /> 
<bean id="newAddress" class="xxx.Address" scope="request" /> 
<bean id="servlet" class="xxx.MyServlet"> 
<property name="currentAddress" ref="currentAddress" /> 
<property name="newAddress" ref="newAddress" /> 
</bean> 


имени сниппет

/* Address class */ 
@Produces @RequestScoped @Named(value="request") 
public Address getNewAddress(){ 
return new Address(); 
} 

@Produces @SessionScoped @Named(value="application") 
public Address getCurrentAddress(){ 
return new Address(); 
} 
/* Servlet */ 
@Inject @RequestScoped @Named("request") private Address newAddress; 
@Inject @ApplicationScoped @Named("application") private Address currentAddress; 

ответ

1

Благодаря @ nsfyn55 за то, что он указал, что good article, прочитав раздел «Правильный путь», я придумал то, что, по моему мнению, лучший способ достичь этого с точки зрения простоты и правильности.

Таким образом, я использую только один интерфейс для аннотации классификатора.

/* Qualifier annotation */ 
@Qualifier 
@Retention(RUNTIME) 
@Target({FIELD,METHOD}) 
public @interface Scope { 

Type value(); 

enum Type { REQUEST, SESSION, APPLICATION }; 
} 


/* Address class */ 
@Produces @Scope(REQUEST) @RequestScoped 
public Address request() { 
return new Address(); 
} 

@Produces @Scope(SESSION) @SessionScoped 
public Address session() { 
return new Address(); 
} 

/* Servlet */ 
@Inject @Scope(REQUEST) 
private Address newAddress; 

@Inject @Scope(SESSION) 
private Address currentAddress; 
2

Причина включения этой рекомендации по той же причине можно было бы предпочесть Перечисление над произвольными строками для константы, и это связано с тем, что он не является безопасным для типа. Вы можете легко ошибочно назвать имя класса, и он будет компилироваться отлично и не работать во время выполнения. Рекомендация включена, потому что в большинстве случаев @named делает ваше приложение излишне хрупким, когда у вас есть способность заставить эти ограничения во время компиляции.

Вот good article, который описывает причины:

Предпочтительный способ справиться с этой ситуацией использует @Qualifiers с перечисленными значениями. Оформить заказ в разделе «Квалификаторы строк - это устаревшие» и «Правильный путь» для шагов по его устранению.

+0

большое спасибо за ваш ответ. Я вижу причины, чтобы препятствовать практике @Named («строка»). После прочтения статьи, которую вы предложили, я пришел с новой идеей, которая мне больше нравится: имеет только один квалификатор для обоих методов. Я попробую это позже. – user454322

+0

Я отредактировал этот пост, который я отметил аннотацией @Qualifier как предпочтительный способ справиться с этим. – nsfyn55

+0

Спасибо, я просто добавил свой ответ с фрагментом – user454322