1

I am working on a Spring Boot application wherein I am using that application to expose a SOAP webservice. I am using Apache CFX framework for SOAP impl in Spring boot app. I am using Annotation based approach.

I am facing issue in setting the Application Context from the Spring Boot Configuration file in one of the Beans. Below is my code.

@SpringBootApplication
@ComponentScan("com.test")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
   }
}

The configuration file is as below.

@Configuration
public class WebServiceConfiguration {

//All individual bean definitions should go here
@Autowired
ApplicationContext appContext;

@Bean
public ServletRegistrationBean cxfServlet() {
    return new ServletRegistrationBean(new CXFServlet(), "/soap-api/*");
}

@Bean(name = Bus.DEFAULT_BUS_ID)
public SpringBus springBus() {
    return new SpringBus();
}


@Bean(name="IValidator")
public IValidator getValidator(){
    return new Validator();
}

@Bean(name="SOAPprocessImpl")
public IPSoap getService() {
    return new SOAPprocessImpl();
}

@Bean
public Endpoint endpoint() {
    EndpointImpl endpoint = new EndpointImpl(springBus(), getService());
    endpoint.publish("/WS_1.0");
    endpoint.setWsdlLocation("process.wsdl");
    return endpoint;
}

Now I have the bean SOAPprocessImpl implementation in which I need to get the Application Context so that I can get handle to the Validator bean. I have declared SOAPprocessImpl as a bean in the configuraton file. The code is as below

@javax.jws.WebService (endpointInterface="com.test.IPSoap")
public class SOAPprocessImpl implements IPSoap, ApplicationContextAware {

private static ApplicationContext context;

public static ApplicationContext getApplicationContext() {
    return context;
}

@Override
public void setApplicationContext(ApplicationContext ac)
        throws BeansException {
    context = ac;
}

private static final Logger logger = Logger.getLogger(SOAPprocessImpl.class.getName());

private IValidator validator = (IValidator) context.getBean("IValidator"); // context is NULL here

public IRResponse GetBalance(TSSearchParams SearchParams) {

    // Some processing logic
    }

}

So the issue is that when I run the boot application by deploying to the embedded Tomcat then the Application Context is not getting set in the SOAPprocessImpl class even after implementing the ApplicationContextAware. I also tried Autowiring but that also is not working.

Strangely I tried to see if I can get the ApplicationContext in the Configuration file where all the bean are defined. Here it is getting setting properly.

Can anyone help me how to solve this issue. I am new to Spring Boot and may have missed some configutaion. Thanks in advance.

1 Answer 1

2

Option(1): To fix the issue, you need to use @Configuration to register your SOAPprocessImpl bean to the Spring container as shown below so that ApplicationContext object can be injected :

@Configuration
@javax.jws.WebService (endpointInterface="com.test.IPSoap")
public class SOAPprocessImpl implements IPSoap, ApplicationContextAware {

   private static ApplicationContext context;

   private IValidator validator;

   public static ApplicationContext getApplicationContext() {
     return context;
   }

   @Override
   public void setApplicationContext(ApplicationContext ac)
      throws BeansException {
      SOAPprocessImpl.context = ac;
   }


   @PostConstruct//use PostConstruct
   public void init() {
     validator = (IValidator) context.getBean("IValidator");
   }


   //add your current code
}

The important point is that you can't use the context object until the bean is prepared by the container, so you need to use @PostConstruct method as shown above to initialise your variables.

Option2 (recommended): The best approach is that you can use @Autowired to inject IValidator object into SOAPprocessImpl as shown below so that you don't need your SOAPprocessImpl bean to be aware of ApplicationContextAware. Spring container will inject the instance for the implementation provided for the IValidator class (provided it is under the packages of @Componentscan).

@Component
@javax.jws.WebService (endpointInterface="com.test.IPSoap")
public class SOAPprocessImpl implements IPSoap {

     private static final Logger logger = Logger.getLogger(SOAPprocessImpl.class.getName());


     @Autowired //spring directly injects this object
     private IValidator validator;

     public IRResponse GetBalance(TSSearchParams SearchParams) {
        // Some processing logic
    }
}
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks . I tried your approach but still its not working. The context is still null.
which package SOAPprocessImpl resides?
SOAPprocessImpl resides in a different package. com.test.config and WebServiceConfiguration resides in other package. com.test.ws
Thanks a lot for clear explanation. Its working now and I am able to get the validator instance from 2nd approach you suggested. have a great day my friend.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.