开发者

replace <constructor-arg> with Spring Annotation

there is a way to replace constructor-arg with Annotation?

I have this constructor:

public开发者_开发知识库 GenericDAOImpl(Class<T> type) {
    this.type = type;
}

and i need to inject that in my Facade:

@Inject
private GenericDAO<Auto, Long> autoDao;

The problem is that i don't know how to pass the value of parameter in costructor.

Thank you in advance

[More Info] I try to explain my problem.

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

I want convert that code using only annotation. Someone can explain how?


I think @Inject alone won't help, you will have to use a @Qualifier annotation also.

Here's the relevant Section of the Spring Reference:
3.9.3 Fine-tuning annotation-based autowiring with qualifiers

If I understand this correctly, you will have to use the @Qualifier mechanism.

If you use Spring's @Qualifier annotation, you can probably do it inline, something like this:

@Repository
public class DaoImpl implements Dao{

    private final Class<?> type;

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

}

But if you use the JSR-330 @Qualifier annotation, I guess you will have to create your own custom annotation that is marked with @Qualifier.


Another possibility would be the @Value annotation. With it you can use Expression Language, e.g. like this:

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


Update: I'm afraid it is not possible to do what you are trying to. You can't get constructor arguments from the parameters of the injection point. A FactoryBean would be the first place to look, but it isn't given the injection point metadata. (To be noted: this case is easily covered by CDI)

Original answer: (that may still work if you configure your types externally)

Simply use @Inject on the constructor. But note that spring frowns upon constructor injection. Consider setter/field injection.

In your case, however, you're likely to have more than one beans of type Class. If this is the case, you can use @Resource(name="beanName").

From the docs of javax.inject.Inject:

Injectable constructors are annotated with @Inject and accept zero or more dependencies as arguments. @Inject can apply to at most one constructor per class.

   @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt)  
   Throwsopt ConstructorBody


An option to have the type in your constructor is:

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

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

but MUST have specific different implementations for each T.

Advantage is that you don't need to pass T type as a parameter.


Spring's Java Configuration might be of help here. If you create a Java class that simply defines your beans using the annotations @Configuration and @Bean it could look something like this:

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

Make sure that the DaoConfiguration class is scanned (typically via @ComponentScan) and a proper DAO-object will be created for you in the Spring context. The bean will have the name of the method which in this case is personDao so you can inject it by name using the name personDao or by type if the type is GenericDAO<Person>.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜