【问题标题】:replace <constructor-arg> with Spring Annotation用 Spring Annotation 替换 <constructor-arg>
【发布时间】:2011-01-06 11:23:07
【问题描述】:

有没有办法用Annotation替换constructor-arg?

我有这个构造函数:

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

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

@Inject
private GenericDAO<Auto, Long> autoDao;

问题是我不知道如何在 costructor 中传递参数的值。

提前谢谢你

[更多信息] 我试图解释我的问题。

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

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

【问题讨论】:

    标签: java spring generics annotations code-injection


    【解决方案1】:

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

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

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

    如果你使用Spring's @Qualifier annotation,你可能可以内联,像这样:

    @Repository
    public class DaoImpl implements Dao{
    
        private final Class<?> type;
    
        public DaoImpl(@Qualifier("type") final Class<?> type){
            this.type = type;
        }
    
    }
    

    但如果你使用JSR-330 @Qualifier annotation,我想你将不得不创建自己的自定义注解,并标有@Qualifier


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

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

    【讨论】:

      【解决方案2】:

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

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

      只需在构造函数上使用@Inject。但请注意,spring 不赞成构造函数注入。考虑 setter/field 注入。

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

      来自javax.inject.Inject的文档:

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

         @Inject ConstructorModifiersopt SimpleTypeName(FormalParameterListopt)  
         Throwsopt ConstructorBody
      

      【讨论】:

      • 我已经使用@Inject,但我也需要传递 Class 类型的值。有办法吗?还是我必须使用 xml 方法?
      • 这个值是多少?你从哪里得到它?
      • @Inject private GenericDAO autoDao;当 GenericDAO 被实例化时,我需要传递 Class type 的值
      【解决方案3】:

      在您的构造函数中使用该类型的选项是:

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

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

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

      【讨论】:

        【解决方案4】:

        Spring 的Java Configuration 在这里可能会有所帮助。如果您创建一个 Java 类,它使用注释 @Configuration@Bean 简单地定义您的 bean,它可能看起来像这样:

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

        确保扫描了DaoConfiguration 类(通常通过@ComponentScan),并且将在Spring 上下文中为您创建适当的DAO 对象。 bean 将具有方法的名称,在本例中为 personDao,因此您可以 按名称 使用名称 personDao按类型 如果类型是GenericDAO&lt;Person&gt;

        【讨论】:

          猜你喜欢
          • 2015-05-16
          • 2020-02-27
          • 1970-01-01
          • 2013-06-20
          • 1970-01-01
          • 1970-01-01
          • 2012-11-20
          • 1970-01-01
          • 2011-07-06
          相关资源
          最近更新 更多