如何使用spring @Lookup注释?

Mil*_*jac 13 java spring dependency-injection

我需要从singleton获得原型类.我发现方法注入是可行的方法,但我真的不知道如何使用spring @Lookup注释.

我是依赖注入的新手,我选择使用注释配置,所以我想继续这个方向.

我发现@Lookup注释最近才被添加(https://spring.io/blog/2014/09/04/spring-framework-4-1-ga-is-here),但我找不到任何地方如何用它.

所以,这是简化的例子

配置类:

@Configuration
@Lazy
public class ApplicationConfiguration implements ApplicationConfigurationInterface {

  @Bean
  public MyClass1 myClass1() {
    return new ContentHolderTabPaneController();
  }

  @Bean
  @Scope("prototype")
  public MyClass2 myClass2() {
    return new SidebarQuickMenuController();
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是类示例:

public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  public MyClass2 myClass2(){
  }
}
Run Code Online (Sandbox Code Playgroud)

如何使用@Lookup注释做到这一点?

qin*_*gbo 31

在将@Lookup注释应用于public MyClass2 myClass2()方法之前,请在@ Lookup的Javadoc中阅读:

容器将通过CGLIB生成方法包含类的运行时子类,这就是为什么这样的查找方法只能在容器通过常规构造函数实例化的bean上工作(即查找方法无法替换从工厂方法返回的bean,我们不能动态地为它们提供子类).

因此从以下方法中删除以下工厂方法样式bean声明ApplicationConfiguration:

  @Bean
  public MyClass1 myClass1() {
    return new ContentHolderTabPaneController();
  }
Run Code Online (Sandbox Code Playgroud)

并添加@Component注释以让Spring实例化bean(也将@Lookup注释添加到方法中):

@Component
public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  @Lookup
  public MyClass2 myClass2(){
    return null; // This implementation will be overridden by dynamically generated subclass
  }
}
Run Code Online (Sandbox Code Playgroud)

现在将myClass1bean从上下文中取出,并且myClass2每次都应该替换/重写其方法以获取新的原型bean.


更新:

使用工厂方法声明

实现带@Lookup注释的方法("查找方法")并不难.如果没有@Lookup并保持配置类不变,现在MyClass1看起来像(事实上,如果@Lookup使用Spring,它会在子类中生成类似的实现):

public class MyClass1 {
  doSomething() {
    myClass2();
  }

  //I want this method to return MyClass2 prototype
  @Autowired
  private ApplicationContext applicationContext;
  public MyClass2 myClass2() {
      return applicationContext.getBean(MyClass2.class);
  }
}
Run Code Online (Sandbox Code Playgroud)

春天注入ApplicationContext你.

  • 但这不是DI的那种失败目的,因为Bean实际上必须要注意DI容器吗? (3认同)

Jos*_*osh 7

如果您不在Spring 4.1上,则可以使用提供者注入:

public class MyClass1 {
  @Autowired
  private Provider<MyClass2> myClass2Provider;

  doSomething() {
    MyClass2 myClass2 = myClass2();
    myClass2.fooBar()
  }

  public MyClass2 myClass2(){
    return myClass2Provider.get();
  }
}
Run Code Online (Sandbox Code Playgroud)

这是DI,IoC,避免了查找方法的抽象类和xml定义.

  • `javax.inject.Provider`准确无误 (4认同)