如何使用spring @Lookup注释?

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

我是dependency injection的新手,我选择使用注释配置,所以我想继续这个方向。

我发现@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注释执行此操作?

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

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

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

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

并添加@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 } } 

现在让myClass1 bean脱离上下文,并且myClass2都应该替换/覆盖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); } } 

Spring为您注入ApplicationContext

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

 public class MyClass1 { @Autowired private Provider myClass2Provider; doSomething() { MyClass2 myClass2 = myClass2(); myClass2.fooBar() } public MyClass2 myClass2(){ return myClass2Provider.get(); } } 

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

此外,您可以使用TARGET_CLASS proxyMode声明myClass2 bean。

  @Bean @Scope("prototype", proxyMode = ScopedProxyMode.TARGET_CLASS) public MyClass2 myClass2() { return new SidebarQuickMenuController(); }