Jax-ws client spring xml bean configuration to java based configuration? - java

Can you help me convert following spring xml based configuration to java based configuration of beans?
<jaxws:client id="helloClient"
serviceClass="demo.spring.HelloWorld"
address="http://localhost:9002/HelloWorld" />

You just need to declare a bean in any of your configuration classes with the properties you have in your question.
It should look something like this:
#Bean(name = "helloClient") // this is the id
public HelloWorld helloWorld() {
String address = "http://localhost:9002/HelloWorld";
JaxWsProxyFactoryBean factoryBean = new JaxWsProxyFactoryBean();
factoryBean.setServiceClass(HelloWorld.class);
factoryBean.setAddress(address);
return (HelloWorld) factoryBean.create();
}
Your method will return an object of the Service class.
You need a Jax proxy factory bean to set the properties and then create the client (cast it to your service class) and return it.

Related

Where do I put my XML beans in a Spring Boot application?

I'm getting back into Spring (currently v4). It's all wonderful now with #SpringBootApplication and the other annotations but all the documentation seems to forget to mention how I define other beans in XML!
For example I'd like to create an "SFTP Session Factory" as defined at:
http://docs.spring.io/spring-integration/reference/html/sftp.html
There is a nice bit of XML to define the bean but where on earth do I put it and how do I link it in? Previously I did a:
ApplicationContext context = new ClassPathXmlApplicationContext(
"classpath:applicationContext.xml");
to specify the file name and location but now that I'm trying to use:
ApplicationContext ctx = SpringApplication.run(Application.class);
Where do I put the XML file? Is there a magic spring name to call it?
As long as you're starting with a base #Configuration class to begin with, which it maybe sounds like you are with #SpringBootApplication, you can use the #ImportResource annotation to include an XML configuration file as well.
#SpringBootApplication
#ImportResource("classpath:spring-sftp-config.xml")
public class SpringConfiguration {
//
}
You also can translate the XML config to a Java config. In your case it would look like:
#Bean
public DefaultSftpSessionFactory sftpSessionFactory() {
DefaultSftpSessionFactory factory = new DefaultSftpSessionFactory();
factory.setHost("localhost");
factory.setPrivateKey(new ClassPathResource("classpath:META-INF/keys/sftpTest"));
factory.setPrivateKeyPassphrase("springIntegration");
factory.setPort(22);
factory.setUser("kermit");
return factory;
}
You can put this method in the class with the #SpringBootApplication annotation.
Spring boot ideal concept is avoid xml file. but if you want to keep xml bean, you can just add #ImportResource("classPath:beanFileName.xml").
I would recommend remove the spring-sftp-config.xml file. And, convert this file to spring annotation based bean. So, whatever class has been created as bean. Just write #Service or #Component annotation before class name. for example:
XML based:
<bean ID="id name" class="com.example.Employee">
Annotation:
#Service or #Component
class Employee{
}
And, add #ComponentScan("Give the package name"). This is the best approach.

Create webservice with configurable endpoint via Spring

I have an application that is trying to access a webservice using generated classes via wsdl2java. I would like to be able to configure it so that I can use a different endpoint based on the environment (TEST/PROD).
I found the following answer to be exactly what I was looking for
https://stackoverflow.com/a/3569291/346666
However, I would like to use Spring to inject an instance of the service into my service layer - is there a pure Spring approach to the above?
Or, is there a better way to inject an instance of a webservice into a class and still be able to dynamically configure the endpoint?
Using Spring Java-based configuration:
#Configuration
public class HelloServiceConfig {
#Bean
#Scope("prototype")
public HelloService helloService(#Value("${webservice.endpoint.address}") String endpointAddress) {
HelloService service = new HelloService();
Hello port = service.getHelloPort();
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,endpointAddress);
return service;
}
}
#Component
public class BusinessService {
#Autowired
private HelloService hellowService;
...
public void setHelloService(HelloService helloService) {
this.helloService = hellowService;
}
}
Edit
To use this with Spring XML-based configuration you just need to register the HelloServiceConfig as a bean in your Spring context xml file:
<bean class="com.service.HelloServiceConfig.class"/>
<bean id="businessService" class="com.service.BusinessService">
<property name="helloService" ref="helloService"/>
</bean>
Other alternatives for creating web service clients in Spring include using Spring Web Services or Apache CXF. Both options allow defining a JAX-WS client based on wsdl2java using only XML but required additional dependencies.

Spring - passing a custom instance to a constructor

I'm trying to implement a command-query design pattern into
a MVC spring based application.
I have, for example, some decorated commands using decorator pattern
like bellow:
ICommandHandler handler =
new DeadlockRetryCommandHandlerDecorator<MoveCustomerCommand>(
new TransactionCommandHandlerDecorator<MoveCustomerCommand>(
new MoveCustomerCommandHandler(
new EntityFrameworkUnitOfWork(connectionString),
// Inject other dependencies for the handler here
)
)
);
How can I inject such a handler into a controller constructor? Where should
I instantiate this handler? A place where this can be instantiated can be
the controller constructor, but this isn't the best solution. Any other ideeas?
Thanks
If you're using PropertyPlaceholderConfigurer (old) or PropertySourcesPlaceholderConfigurer (new), and your connection string is in a .properties file or environment variable you can do the following for the connection string. You can also autowire objects into a configuration class and annotate a method with #Bean to do what the Spring context xml does. With this approach you can create your beans as you wish and they're available to autowire just like you defined them in xml.
#Configuration
public class MyAppConfig {
#Autowired private MyType somethingToAutowire;
#Bean
public ICommandHandler iCommandHandler(#Value("${datasource.connectionString}")
final String connectionString) {
return new DeadlockRetryCommandHandlerDecorator<MoveCustomerCommand>();
// You obviously have access to anything autowired in your configuration
// class. Then you can #Autowire a ICommandHandler type into one of your
// beans and this method will be called to create the ICommandHandler (depending on bean scope)
}
}

Spring XML + properties configuration to Java Class

I have the following configuration piece on my xml file:
<util:properties id="apiConfigurator" location="classpath:api.properties" scope="singleton"/>
And here is my properties file:
appKey=abc
appSecret=def
On my spring classes I get some of the values like this:
#Value("#{apiConfigurator['appKey']}")
I would like to create a #Configuration class in Spring to parse the properties file in a way that
#Value("#{apiConfigurator['appKey']}")
still works thorough my classes that use this. How do I properly do that?
When you specify
<util:properties .../>
Spring registers a PropertiesFactoryBean bean with the name/id that you also specified.
All you need to do is to provide such a #Bean yourself
// it's singleton by default
#Bean(name = "apiConfigurator") // this is the bean id
public PropertiesFactoryBean factoryBean() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("api.properties"));
return bean;
}

Spring configuration

Let's say we have a bean definition in spring configuration
<bean id="scanningIMAPClient" class="com.acme.email.incoming.ScanningIMAPClient" />
What I really want is the scanningIMAPClient to be of type com.acme.email.incoming.GenericIMAPClient if the configured email server is a normal IMAP server and com.acme.email.incoming.GmailIMAPClient incase it is a GMAIL server, (since gmail behaves in slightly different way) GmailIMAPClient is a subclass of GenericIMAPClient.
How can I accomplish that in spring configuration?
There is a properties file which contains configuration of the email server.
It's simple with Java configuration:
#Value("${serverAddress}")
private String serverAddress;
#Bean
public GenericIMAPClient scanningIMAPClient() {
if(serverAddress.equals("gmail.com"))
return new GmailIMAPClient();
else
return new GenericIMAPClient();
}
You can emulate this behaviour with custom FactoryBean.
You can use programatic configuration:
#Configuration
public class AppConfig {
#Bean(name="scanningIMAPClient")
public GenericIMAPClient helloWorld() {
...check config and return desired type
}
}
More info here.

Categories

Resources