замещатьс весенней аннотацией - PullRequest
8 голосов
/ 06 января 2011

есть ли способ заменить конструктор-аргумент аннотацией?

У меня есть этот конструктор:

public GenericDAOImpl(Class<T> type) {
    this.type = type;
}

, и мне нужно ввести это в мой фасад:

@Inject
private GenericDAO<Auto, Long> autoDao;

Проблема в том, что я не знаю, как передать значение параметра в конструкторе.

Заранее спасибо

[Подробнее] Я пытаюсь объяснить свою проблему.

<bean id="personDao" class="genericdao.impl.GenericDaoHibernateImpl">
        <constructor-arg>
            <value>genericdaotest.domain.Person</value>
        </constructor-arg>
</bean>

Я хочу преобразовать этот код, используя только аннотации.Кто-то может объяснить, как?

Ответы [ 4 ]

4 голосов
/ 06 января 2011

Я думаю, что @Inject само по себе не поможет, вам также придется использовать аннотацию @Qualifier.

Вот соответствующий раздел ссылки на источник:
3.9.3 Тонкая настройка автосвязи на основе аннотаций с классификаторами

Если я правильно понимаю, вам придется использовать механизм @Qualifier.

Если вы используете аннотацию @Qualifier Spring , вы, вероятно, можете сделать это встроенным, что-то вроде этого:

@Repository
public class DaoImpl implements Dao{

    private final Class<?> type;

    public DaoImpl(@Qualifier("type") final Class<?> type){
        this.type = type;
    }

}

Но если вы используете аннотацию JSR-330 @Qualifier , я думаю, вам придется создать свою собственную пользовательскую аннотацию, помеченную @Qualifier.


Другой возможностью будет аннотация @Value. С ним вы можете использовать Expression Language, например, как это:

public DaoImpl(
    @Value("#{ systemProperties['dao.type'] }")
    final Class<?> type){
    this.type = type;
}
2 голосов
/ 26 апреля 2012

Вариант иметь тип в вашем конструкторе:

public abstract class GenericDAO<T> {
    private Class<T> persistentClass;

    public GenericDAO() {
        this.persistentClass = (Class<T>) ((ParameterizedType) getClass()
            .getGenericSuperclass()).getActualTypeArguments()[0];
    }
...
}

, но ДОЛЖЕН иметь конкретные реализации для каждого T.

Преимущество заключается в том, что вам не нужно передавать Tвведите в качестве параметра.

2 голосов
/ 06 января 2011

Обновление: Боюсь, невозможно сделать то, что вы пытаетесь.Вы не можете получить аргументы конструктора из параметров точки внедрения.FactoryBean будет первым местом для поиска, но в нем нет метаданных точки внедрения.(Следует отметить: этот случай легко охватывается CDI)

Оригинальный ответ: (это может все еще работать, если вы настраиваете свои типы внешне)

Просто используйте @Inject на конструкторе.Но обратите внимание, что пружина хмурится после инжектора конструктора.Подумайте о введении сеттера / поля.

В вашем случае, однако, у вас может быть более одного компонента типа Class.Если это так, вы можете использовать @Resource(name="beanName").

Из документов javax.inject.Inject:

Инжектируемые конструкторы аннотируются @Inject и принимают ноль или более зависимостей в качестве аргументов.@Inject может применяться не более чем к одному конструктору на класс.

   @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt)  
   Throwsopt ConstructorBody
0 голосов
/ 22 декабря 2014

Spring's Java Configuration может помочь здесь. Если вы создадите Java-класс, который просто определяет ваши компоненты с помощью аннотаций @Configuration и @Bean, это может выглядеть примерно так:

@Configuration
public class DaoConfiguration {
    @Bean
    public GenericDAO<Person> personDao() {
        return new GenericDaoHibernateImpl(Person.class);
    }
}

Убедитесь, что класс DaoConfiguration сканируется (обычно через @ComponentScan), и в контексте Spring будет создан соответствующий объект DAO. Боб будет иметь имя метода, которое в данном случае равно personDao, поэтому вы можете внедрить его по имени , используя имя personDao или по типу , если тип GenericDAO<Person>.

...