【问题标题】:Autowiring in Spring bean (@Component) created with new keyword在使用 new 关键字创建的 Spring bean (@Component) 中自动装配
【发布时间】:2012-06-15 08:39:37
【问题描述】:

我有两个春豆如下:

@Component("A")
@Scope("prototype")
public class A extends TimerTask {

    @Autowired
    private CampaignDao campaignDao;
    @Autowired
    private CampaignManager campManger;
    A(){
        init_A();
       }
    }

由于遗留代码,我必须使用 new 关键字创建 A 的新对象

@Component("B")
@Scope("prototype")
public class B{
     public void test(){
       A a = new A();
     }
}

当运行 -> 类 A 中的 spring bean 为空时,我可以创建一个新的 spring bean A 实例并仍然在其中使用自动装配吗?

【问题讨论】:

  • 您是否在 Spring bean 定义文件中定义了 campaignDaocampManger

标签: java spring jakarta-ee dependency-injection


【解决方案1】:

您的组件“A”不是由 Spring 容器创建的,因此不会注入依赖项。但是,如果您需要支持一些遗留代码(正如我从您的问题中了解到的那样),您可以使用 @Configurable 注释和构建/编译时编织:

@Configurable(autowire = Autowire.BY_TYPE)
public class A extends TimerTask {
  // (...)
}

然后,Spring 将向组件 A 注入自动装配的依赖项,无论它是由容器本身实例化的,还是由 new 在某些遗留代码中实例化的。

例如,要使用 maven 插件设置构建时编织,您必须:

  1. <context:spring-configured/> 添加到 Spring 应用程序上下文中
  2. 配置Maven AspectJ plugin:

在构建插件部分:

<build>
  <plugins>
    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>aspectj-maven-plugin</artifactId>
      <version>1.4</version>
      <configuration>
        <complianceLevel>1.6</complianceLevel>
        <encoding>UTF-8</encoding>
        <aspectLibraries>
          <aspectLibrary>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aspects</artifactId>
          </aspectLibrary>
        </aspectLibraries>
        <!-- 
          Xlint set to warning alleviate some issues, such as SPR-6819. 
          Please consider it as optional.
          https://jira.springsource.org/browse/SPR-6819
        -->
        <Xlint>warning</Xlint>
      </configuration>
      <executions>
        <execution>
          <goals>
            <goal>compile</goal>
            <goal>test-compile</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

...以及依赖项部分:

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>3.1.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.aspectj</groupId>
  <artifactId>aspectjrt</artifactId>
  <version>1.6.11</version>
</dependency>

更多详情请参考 Spring 参考: http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable

【讨论】:

  • A 类在其他类中使用关键字 new 进行实例化,在使用关键字 new 创建新对象后,我还能在 A 类中进行自动装配吗?
  • 是的 - 请查看我发布的 Spring 参考文档中的章节。可以使用@Configurable 注释和编译/加载时间编织。
  • 好吧,我制作了由 new 关键字 @Configurable(autowire = Autowire.BY_TYPE) 创建的 spring bean 并且仍然得到相同的行为,那么我错过了什么?编译/加载时间编织是什么意思
  • 为此,必须在编译时(使用 ant 或 maven 插件)或运行时(参见 static.springsource.org/spring/docs/current/…)编织带注释的类型。我已经更新了答案以包含构建时编织的示例配置 - 这是我使用的。
  • 当通过新关键字创建 bean 时,'@Autowired' 字段仍然为空。所以我错过了什么? @Piotrek De
【解决方案2】:

因为您是使用 new 运算符自己创建类 A 的对象,所以您不会在该对象中获取自动装配的字段并发现它们为空。尝试从 spring 容器中获取 bean。

希望这对您有所帮助。干杯。

【讨论】:

  • 我必须从 A 创建一个新对象,我可以从 A 创建一个新对象并且仍然能够在 A 中自动装配
  • 不,不可能。相反,您应该将 bean A 声明为原型。这样每次你请求它的对象时,它都会给你一个用它的属性初始化的新对象。该对象中的自动装配字段将适用于您。 :-)
猜你喜欢
  • 2014-06-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-11-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多