замените ‹constructor-arg› на аннотацию Spring

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

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

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>

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


person Roberto de Santis    schedule 06.01.2011    source источник


Ответы (4)


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

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

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

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

@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 аннотация. С ним вы можете использовать язык выражений, например. как это:

public DaoImpl(
    @Value("#{ systemProperties['dao.type'] }")
    final Class<?> type){
    this.type = type;
}
person Sean Patrick Floyd    schedule 06.01.2011

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

Исходный ответ: (это может по-прежнему работать, если вы настроите свои типы извне)

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

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

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

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

   @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt)  
   Throwsopt ConstructorBody
person Bozho    schedule 06.01.2011
comment
Я уже использую @Inject, но мне нужно также передать значение типа Class‹T›. Есть способ сделать это? или я должен использовать xml-подход? - person Roberto de Santis; 06.01.2011
comment
что это за ценность? Откуда вы это взяли? - person Bozho; 06.01.2011
comment
@Inject private GenericDAO‹Auto, Long› autoDao; когда GenericDAO был создан, мне нужно передать значение типа Class‹T› - person Roberto de Santis; 06.01.2011

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

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

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

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

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

person danidacila    schedule 26.04.2012

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

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

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

person wassgren    schedule 21.12.2014