java 用 Spring Annotation 替换 <constructor-arg>

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4614349/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:13:40  来源:igfitidea点击:

replace <constructor-arg> with Spring Annotation

javaspringgenericsannotationscode-injection

提问by Roberto de Santis

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:

我需要在我的 Facade 中注入它:

@Inject
private GenericDAO<Auto, Long> autoDao;

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

问题是我不知道如何在 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?

我只想使用注释转换该代码。有人可以解释一下吗?

回答by Sean Patrick Floyd

I think @Injectalone won't help, you will have to use a @Qualifierannotation also.

我认为@Inject单独无济于事,您还必须使用@Qualifier注释。

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

这是 Spring 参考的相关部分:
3.9.3 Fine-tuning annotation-based autowiring with qualifiers

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

如果我理解正确,您将不得不使用该@Qualifier机制。

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

如果您使用Spring 的@Qualifierannotation,您可能可以内联进行,如下所示:

@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 @Qualifierannotation, I guess you will have to create your own custom annotation that is marked with @Qualifier.

但是,如果您使用JSR-330@Qualifier注释,我猜您将不得不创建自己的标记为@Qualifier.



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

另一种可能性是@Value注释。有了它,您可以使用表达式语言,例如:

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

回答by danidacila

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.

但必须对每个 T 有特定的不同实现。

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

优点是不需要将 T 类型作为参数传递。

回答by Bozho

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 FactoryBeanwould 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)

更新:恐怕不可能做你想做的事。您无法从注入点的参数中获取构造函数参数。AFactoryBean将是第一个查看的地方,但它没有给出注入点元数据。(需要注意的是:这种情况很容易被 CDI 覆盖)

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

原始答案:(如果您在外部配置类型,这可能仍然有效)

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

只需@Inject在构造函数上使用。但请注意,spring 对构造函数注入不屑一顾。考虑设置器/字段注入。

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").

但是,在您的情况下,您可能拥有多个类型的 bean Class。如果是这种情况,您可以使用@Resource(name="beanName").

From the docs of javax.inject.Inject:

来自以下文档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

可注入构造函数使用 @Inject 进行注释,并接受零个或多个依赖项作为参数。@Inject 最多可以应用于每个类一个构造函数。

   @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt)  
   Throwsopt ConstructorBody

回答by wassgren

Spring's Java Configurationmight be of help here. If you create a Java class that simply defines your beans using the annotations @Configurationand @Beanit could look something like this:

Spring 的Java 配置在这里可能会有所帮助。如果您创建一个仅仅使用豆类注释定义了一个Java类@Configuration@Bean它可能是这个样子:

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

Make sure that the DaoConfigurationclass 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 personDaoso you can inject it by nameusing the name personDaoor by typeif the type is GenericDAO<Person>.

确保DaoConfiguration扫描了类(通常通过@ComponentScan),并且会在 Spring 上下文中为您创建适当的 DAO 对象。bean 将具有方法的名称,在这种情况下personDao,您可以使用名称或类型(如果类型为 )按名称注入它。personDaoGenericDAO<Person>