如何使用弹簧@Lookup注解?使用工厂方法声明

2022-09-03 03:53:37

我需要从单例中获取原型类。我发现方法注入是要走的路,但我真的不知道如何使用弹簧@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();
  }
}

下面是类示例:

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

  //I want this method to return MyClass2 prototype
  public MyClass2 myClass2(){
  }
}

如何使用@Lookup注释执行此操作?


答案 1

在将注释应用于您的方法之前,请在@Lookup的Javadoc中阅读以下内容:@Lookuppublic MyClass2 myClass2()

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

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

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

并添加注释以让Spring实例化bean(也将注释添加到方法中):@Component@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
  }
}

现在,脱离上下文获取Bean,并且其方法应该被替换/覆盖,以便每次都获得新的原型Bean。myClass1myClass2


更新

使用工厂方法声明

实现带注释的方法(“查找方法”)并不难。没有并保持配置类不变,现在看起来像这样(实际上,如果使用了Spring,则会在子类中生成类似的实现):@Lookup@LookupMyClass1@Lookup

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);
  }
}

春天为你注入。ApplicationContext


答案 2

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

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

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

  public MyClass2 myClass2(){
    return myClass2Provider.get();
  }
}

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


推荐