有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使用spring@Lookup注释?

我需要从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();
  }
}

下面是课堂示例:

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

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

如何使用@Lookup注释实现这一点


共 (3) 个答案

  1. # 1 楼答案

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

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

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

    the container will generate runtime subclasses of the method's containing class via CGLIB, which is why such lookup methods can only work on beans that the container instantiates through regular constructors (i.e. lookup methods cannot get replaced on beans returned from factory methods where we can't dynamically provide a subclass for them).

    因此,从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
      }
    }
    

    现在从上下文中获取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);
      }
    }
    

    Spring为您注入ApplicationContext

  3. # 3 楼答案

    如果您没有使用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定义