【问题标题】:Spring Auto Components Scanning with Constructor injection使用构造函数注入进行 Spring Auto 组件扫描
【发布时间】:2013-05-22 14:01:42
【问题描述】:

我知道如何单独使用自动组件扫描和构造函数注入。 http://www.mkyong.com/spring/spring-auto-scanning-components/ http://www.dzone.com/tutorials/java/spring/spring-bean-constructor-injection-1.html

是否可以使用带有构造函数注入的自动组件扫描?在使用自动组件扫描时,spring 框架会扫描所有指向 "base-package" 的类,并通过调用每个不带参数的构造函数来创建每个类的实例。让我们说一下如何修改以下类和相关的spring XML文件。

package com.fb.common;
@Repository
public class Person {

    private String name;
    private int age;

    public Person(String name, int age){
        this.name=name;
        this.age=age;
    }

    public String toString(){
        return "Name: "+name+" Age:"+age;
    }

}

XML 文件

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd">

    <context:component-scan base-package="com.fb.common" />

    <!--
    <bean id="person" class="com.fb.common.Person">
        <constructor-arg type="java.lang.String" value="DefaultName"/>
        <constructor-arg type="int" value="30"/>
    </bean>
    -->
</beans>

【问题讨论】:

  • 对于@Value注解,依赖的groupdId和artifactId是什么
  • 应该在spring-context,看我的回答。
  • 我的项目没有找到@inject注解类定义。据我所知,它是 Java 自带的
  • 没有,但你可以使用 Spring 的@Autowired 代替。

标签: java spring jakarta-ee


【解决方案1】:

您可以执行以下操作

@Inject // or @Autowired
public Person(@Value("DefaultName") String name, @Value("30") int age){
    this.name=name;
    this.age=age;
}

根据 Bozho 的回答 herespring 对构造函数注入皱眉。也许你不应该这样做。

对于您的问题的评论,它应该在

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${org.springframework-version}</version>
</dependency>

对于@Inject,您需要

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

但是你可以使用 Spring 提供的@Autowired

【讨论】:

  • 我不确定“构造函数注入时的春天皱眉”评论。据我所知,spring 鼓励你使用适合你的 java 代码的任何东西。
  • @gkamal 只是把它放在那里,还有这篇文章:steveschols.wordpress.com/2012/06/05/…。使用您的问题中的属性占位符,情况会好一些。
  • 可能有点晚了,但是......从历史上看,Spring 支持属性注入,但几年前从现在转向支持构造函数注入“必需”依赖项。
【解决方案2】:

您需要为每个构造函数参数添加@Value 注释

public Person(@Value("DefaultName")String name, @Value("30")int age){
    this.name=name;
    this.age=age;
}

您可以使用属性占位符来引用属性文件中定义的属性,而不是对值进行硬编码。

public Person(@Value("${person.defaultName}")String name, @Value("${person.age}")int age){
    this.name=name;
    this.age=age;
}

像 Person(实体值对象)这样的类通常不会创建为 spring bean。

【讨论】:

  • 你的意思是, 谢谢。
【解决方案3】:

如果启用了组件扫描,spring 将尝试创建一个 bean,即使该类的 bean 已经在 spring config xml 中定义。但是,如果 spring 配置文件中定义的 bean 和自动发现的 bean 具有相同的名称,那么 spring 在进行组件扫描时将不会创建新的 bean。如果 bean 没有无参数构造函数,则至少一个构造函数必须是自动连接的。如果没有自动连接构造函数,spring 将尝试使用默认的无参数构造函数创建对象。你可以找到更多关于这个话题here

【讨论】:

    猜你喜欢
    • 2012-05-19
    • 2011-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-01
    相关资源
    最近更新 更多