2017-08-17 98 views
0

Spring中是否有一種機制爲泛型bean構造的自動化提供了一種方法?Spring通用bean工廠

爲,例如,如果我有一個類定義,如:

class Foo<T> { 
    private final T type; 
    ... 
} 

和依賴性,如:

@Autowired 
private Foo<String> foo; 

我想使用在Spring中的一些機制提供以某種形式, T從依賴關係定義(在上面的例子中,字符串),並提供了一種自動創建實例的方法?

回答

1

通過在你的Spring配置定義的:

@Bean 
public Foo<String> foo() { 
    return new Foo<>("bar"); 
} 

或替代的價值,你可以指定類型:

@Bean 
public Foo<String> foo() { 
    return new Foo<>(String.class); 
} 

如果你使用Spring啓動,您可以添加@ConditionalOnProperty@ConditionalOnBean動態化bean實例。

(更新)如果您想避免申報,您應該延長DefaultListableBeanFactoryApplicationContext。這裏是春天引導工作的例子:

@Controller 
@EnableAutoConfiguration 
public class BeanFactoryTest { 
    public static void main(String[] args) throws Exception { 
     SpringApplication app = new SpringApplication(BeanFactoryTest.class); 
     app.setApplicationContextClass(CustomAppContext.class); 
     app.run(args); 
    } 

    @Autowired 
    private Foo<String> foo1; 

    @Autowired 
    private Foo<String> foo2; 

    @Autowired 
    private Foo<Integer> foo3; 

    @PostConstruct 
    public void initialize() { 
     System.out.println(foo1); // prints [email protected] 
     System.out.println(foo2); // prints [email protected] 
     System.out.println(foo3); // prints [email protected] 
    } 

    public static class CustomAppContext extends AnnotationConfigApplicationContext { 
     public CustomAppContext() { 
      super(new CustomBeanFactory()); 
     } 
    } 

    public static class CustomBeanFactory extends DefaultListableBeanFactory { 
     @Override 
     protected Map<String, Object> findAutowireCandidates(String beanName, Class<?> requiredType, DependencyDescriptor descriptor) { 
      Map<String, Object> map = super.findAutowireCandidates(beanName, requiredType, descriptor); 

      if (Foo.class.isAssignableFrom(requiredType)) { 
       ResolvableType type = ResolvableType.forField(descriptor.getField()); 
       ResolvableType genericType = type.getGeneric(0); 
       Class<?> genericTypeRaw = genericType.getRawClass(); 

       boolean hasInstance = 
         map.values() 
          .parallelStream() 
          .map(Foo.class::cast) 
          .map(Foo::getType) 
          .filter(genericTypeRaw::isAssignableFrom) 
          .findFirst() 
          .isPresent(); 

       if (!hasInstance) { 
        super.registerResolvableDependency(requiredType, new Foo<>(genericTypeRaw)); 

        map = super.findAutowireCandidates(beanName, requiredType, descriptor); 
       } 
      } 

      return map; 
     } 
    } 

    public static class Foo<T> { 
     private final Class<T> type; 

     public Foo(Class<T> type) { 
      this.type = type; 
     } 

     public Class<T> getType() { 
      return type; 
     } 
    } 
} 
+0

我添加了一個實現。工作,但可以優化。 –

相關問題