2017-06-09 24 views
4

我需要一個Component在另一個之前被初始化。隨着@DependsOn它會是這個樣子:Spring @DependsOn註釋是否存在「還原」?

@Component("beana") 
public class BeanA{ 

    @PostConstruct 
    void init(){ 
     // do smth 
    } 
} 

@Component("beanb") 
@DependsOn("beana") 
public class BeanB{ 

    @PostConstruct 
    void init(){ 
     // do smth 
    } 
} 

我現在要告訴BeanB,這取決於BeanA的初始化。 我的問題是,我不希望BeanB知道BeanAs存在(例如,當BeanB只是在初始化時發佈EventBus中的事件並且BeanA處理這些事件時)。我想在BeanA中使用一個註釋,聲明它應該在BeanB之前初始化。所以它會是這樣的:

@Component("beana") 
@RequiredBy("beanb") 
public class BeanA{ 

    @PostConstruct 
    void init(){ 
     // do smth 
    } 
} 

@Component("beanb") 
public class BeanB{ 

    @PostConstruct 
    void init(){ 
     // do smth 
    } 
} 

是否有任何Spring註釋或可能性來處理它是這樣的?

+0

使用'@ Order'註解 – pvpkiran

回答

1

我相信這裏沒有開箱即可的春季註釋,但是您可以輕鬆地製作出自己的一個。

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.TYPE) 
public @interface RequiredBy { 
    String[] value(); 
} 

則可以通過所有的bean定義進行迭代,並設置dependsOn到required豆。

@Component 
public static class RequiredByBeanDefinitionPostProcessor implements BeanDefinitionRegistryPostProcessor { 

    @Override 
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { 
     for (String beanName : registry.getBeanDefinitionNames()) { 
      final BeanDefinition beanDefinition = registry.getBeanDefinition(beanName); 
      if (beanDefinition.getBeanClassName() == null) { 
       continue; 
      } 
      try { 
       final Class<?> beanClass = Class.forName(beanDefinition.getBeanClassName()); 
       if (beanClass.isAnnotationPresent(RequiredBy.class)) { 
        final String[] dependantBeanNames = beanClass.getAnnotation(RequiredBy.class).value(); 
        for (String dependantBeanName : dependantBeanNames) { 
         BeanDefinition dependantBeanDefinition = registry.getBeanDefinition(dependantBeanName); 
         dependantBeanDefinition.setDependsOn(beanName); 
        } 
       } 
      } 
      catch (ClassNotFoundException e) { throw new RuntimeException(e); } 
     } 
    } 

    @Override 
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { } 
} 

,然後使用它就像你例如:

@Component("beanA") 
public static class BeanA { 
    @PostConstruct 
    private void init() { 
     System.out.println(this.getClass().getSimpleName()); 
    } 
} 

@Component("beanB") 
@RequiredBy({ "beanC", "beanA" }) 
public static class BeanB { 
    @PostConstruct 
    private void init() { 
     System.out.println(this.getClass().getSimpleName()); 
    } 
} 

@Component("beanC") 
@RequiredBy("beanA") 
public static class BeanC { 
    @PostConstruct 
    private void init() { 
     System.out.println(this.getClass().getSimpleName()); 
    } 
} 

=>

BeanB 
BeanC 
BeanA 
0

可以使用@Order註釋所推薦的pvpkiran

您的代碼將是這個樣子:

@Component("beana") 
@Order(1) 
public class BeanA{ 

@PostConstruct 
    void init(){ 
     // do smth 
    } 
} 

@Component("beanb") 
@Order(2) 
public class BeanB{ 

    @PostConstruct 
    void init(){ 
     // do smth 
    } 
}