2

I have a set of service classes that are spread across different maven modules in my application.

public class ServiceA implements IsService
{
   public void startA()
   {
       ....
   }
}

public class ServiceB implements IsService
{
   public void startB()
   {
       ....
   }
}

Creating a configuration class to detect and register only the classes that implement the IsService interface.

@Configuration
@ComponentScan(basePackages = {"com.subex.roc"} , 
              useDefaultFilters = false , 
              includeFilters = {@Filter(type = FilterType.ASSIGNABLE_TYPE,value = IsService.class)})
public class ServiceRegisterConfig 
{
}

Fetching the registered classes and calling start() polymorphically.

  public void initServerServices()
    {
        AnnotationConfigApplicationContext context = new  AnnotationConfigApplicationContext();
        context.register(ServiceRegisterConfig.class);
        context.refresh();

        for (String beanDfn : context.getBeanDefinitionNames()) 
        {
          if (context.getBean(beanDfn) instanceof IsService) {
          IsService service = (IsService) context.getBean(beanDfn);
          service.start();
        }
     } 
    }

However I want to ensure that ServiceA 's start() is called first and then ServiceB as ServiceB depends on the initialization of ServiceA. Can the container somehow ensure this?

Tried DependsOn. But start() of services being called in the order of their encounter in classpath.DependsOn not being honoured.

Priyanka.Patil
  • 1,177
  • 2
  • 15
  • 34
  • 1
    Possible duplicate of [Spring: Make sure a particular bean gets initialized first](http://stackoverflow.com/questions/7868335/spring-make-sure-a-particular-bean-gets-initialized-first) – Software Engineer Mar 28 '16 at 03:37

2 Answers2

1

Use the depends-on attribute, but if you get into trouble you can always hack in a post processor factory...

public class PreInitializer implements BeanFactoryPostProcessor, PriorityOrdered {  
 @Override  
 public int getOrder() {  
  return Ordered.HIGHEST_PRECEDENCE;  
 }  
 @Override  
 public void postProcessBeanFactory(  
   ConfigurableListableBeanFactory beanFactory) throws BeansException {  
  /* put initialization code here */  
 }  
}  
Software Engineer
  • 15,457
  • 7
  • 74
  • 102
  • Implementing PriorityOrdered would mean I have to go and update the services classes.I'm looking for a solution where I can define this order externally.depends-on seems viable.Is there is java-based or annotation based alternative for depends-on? – Priyanka.Patil Mar 28 '16 at 03:52
  • @Priyanka.Patil you can use `DependsOn` annotation on declarations of your beans. But in this case you have to declare every bean manually in configuration class. – Ken Bekov Mar 28 '16 at 04:04
  • Tried `DependsOn`. But start() of services being called in the order of their encounter in classpath.`DependsOn` not being honoured. – Priyanka.Patil Mar 28 '16 at 07:00
0

BeanFactoryPostProcessor can be used to set dependencies

public class DependencyConfigurer implements BeanFactoryPostProcessor, PriorityOrdered {

    @Override  
 public int getOrder() {  
  return Ordered.HIGHEST_PRECEDENCE;  
 } 

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

            BeanDefinition bd = beanFactory.getBeanDefinition("serviceB");
            bd.setDependsOn("serviceA");


    }



}

Alternatively you can use DependsOn annotation

@Bean(name="ServiceA") 
   public class ServiceA implements IsService
    {
       public void startA()
       {
           ....
       }
    }

@Bean(name="ServiceB")
@DependsOn("ServiceA")
public class ServiceB implements IsService
{
   public void startB()
   {
       ....
   }
}

Finally XML configuration can be used

<bean class="com.foo.ServiceA" name="serviceA"/>

<bean class="com.foo.ServiceB" depends-on="serviceA"/>
Sanj
  • 3,879
  • 2
  • 23
  • 26