Is it possible to construct an object partially with Spring DI and partially with Jersey DI? - spring

I have a class JerseyWebService which uses Jersey DI to inject dependency
#Path("/baskets")
public class JerseyWebService {
#Inject
ExternalApiServiceInterface api;
...
}
The dependency is specified in the binder
public class CustomBinder extends AbstractBinder {
#Override
protected void configure() {
bind(ExternalApiService.class).to(ExternalApiServiceInterface.class);
...
}
But the problem here is that ExternalApiService has other dependencies and it uses Spring to inject them.
class ExternalApiService implements ExternalApiServiceInterface{
#Autowired
AnotherService aservice;
Is it possible to specify only some dependencies in binder which Jersey will Inject and other dependencies being injected by Spring ?
If not ,then if had been #Inject instead of #Autowired in ExternalApiService would it be mandatory to specify all bindings in the binder class?
Does Jersey DI has no Autowiring like feature or delegate injecting a dependency to Spring if it can't find any binding?

It should work. Given you have the required Spring-Jersey integration dependency[1] and have correctly configured the application[2]
1. See Spring DI support in Jersey
2. See official Jersey Spring example
What happens is HK2 (Jersey's DI framework) will look for an InjectionResolver for the #Autowired annotation, in order to resolve the dependency. The jersey-spring3 dependency has the AutowiredInjectionResolver, which holds a reference to Spring's ApplicationContext. From there it's just matter of looking it up in the application context, to resolve the dependency.

Related

Spring Boot Dependency with Spring 3

I have a Spring 3 dependent project which I am using in my latest spring boot project
I am facing issues with auto wiring
my spring 3 project has a Gateway Interface (IAccountGateway)
I am facing an issue like
Description:<br>
<br>Field iAccountGateway in
com.rvi.service.common.impl.RegistrationService required a bean of type
'com.rvi.jms.gateway.IAccountGateway' that could not be found. <br><br>Action:<br>
Consider defining a bean of type 'com.rvi.jms.gateway.IAccountGateway'
in your configuration.
when I put debug in my spring project I got log something like below
Registered injected element on class <br><br>
[com.rvi.service.common.impl.RegistrationService]:
AutowiredFieldElement for private com.rvi.jms.gateway.IAccountGateway
com.rvi.service.common.impl.RegistrationService.iAccountGateway
Well, if IAccountGateway is an interface, then, you need to implement it and define as a Spring Bean with #Component annotation (there are also other annotations that have similar effect).
IAccountGateway.java
public interface IAccountGateway {
// ..
}
AccountGatewayImpl.java (the IAccountGateway implementation)
import org.springframework.stereotype.Component;
#Component
public class AccountGatewayImpl implements IAccountGateway {
// ..
}
Autowiring the field:
import org.springframework.beans.factory.annotation.Autowired;
public class Clazz {
#Autowired
IAccountGateway iAccountGateway;
// ..
}
See Spring Boot Reference on Spring Beans and Dependency Injection

Spring Boot Application with dependency having multiple datasources

I am trying to create a Spring Boot Application, with a dependency jar which has got context.xml configured with multiple datasources.
In My spring boot application, I added #ImportResource("context.xml") to the #Configuration class and now, I get an exception that
"No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 4: XXXDataSource,YYYDataSource,ZZZDataSource,aaaaDataSource".
I read the documentation on multiple datasources in Spring Boot, but unable to fix this issue. Not sure, how I can configure my class, as I cannot change the dependency jar to change the way datasources are configured.
Please help!
You can use the "Primary" attribute on your datasource bean to make your autowiring choose it by default.
<bean primary="true|false"/>
If you are using Java configuration, use the #Primary annotation instead.
http://docs.spring.io/spring-framework/docs/4.0.4.RELEASE/javadoc-api/org/springframework/context/annotation/Primary.html
#Component
public class FooService {
private FooRepository fooRepository;
#Autowired
public FooService(FooRepository fooRepository) {
this.fooRepository = fooRepository;
}
}
#Component
public class JdbcFooRepository {
public JdbcFooService(DataSource dataSource) {
// ...
}
}
#Primary
#Component
public class HibernateFooRepository {
public HibernateFooService(SessionFactory sessionFactory) {
// ...
}
}
If this still doesn't resolve the issue, you can name the bean, and use the #Qualifier annotation in your java classes, or use the "ref" attribute in your Spring XML configuration.
https://spring.io/blog/2014/11/04/a-quality-qualifier
#Autowired
#Qualifier( "ios") // the use is unique to Spring. It's darned convenient, too!
private MarketPlace marketPlace ;
If you require one of the datasources in the jar and are unable to modify the configuration, rather than importing the xml from the jar, copy the configurations you need into your own local spring context configuration.

Autowire specific implementations of persistence layer in Spring with Java based configuration

In a Spring MVC proyect I'm using Spring Data in the persistence layer so I have a bunch of repositories to access the data. I also have a layer for services so I have things like UserService or AuthorityService that use that repositories.
The problem is that I've been asked to create an interface to be able to change the implementation of the persistence layer (using DAOs for example) without have to touch a single line in the services. How can I specify in an Autowired of that interface what implementation to use? I´m using Java based config and I don't see how to inject it.
I also have a problem with the name of these new interfaces. Normally I would use a name like UserService but Spring use Service for the service layer so, What name is suitable for this type of interface?
You could mark the new implementation of the DAO as #Primary. Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency. If exactly one 'primary' bean exists among the candidates, it will be the autowired value.
#Component
public class FooService {
private FooRepository fooRepository;
#Autowired
public FooService(FooRepository fooRepository) {
this.fooRepository = fooRepository;
}
}
#Component
public class JdbcFooRepository {
public JdbcFooService(DataSource dataSource) {
// ...
}
}
#Primary
#Component
public class HibernateFooRepository {
public HibernateFooService(SessionFactory sessionFactory) {
// ...
}
}
Because HibernateFooRepository is marked with #Primary, it will be injected preferentially over the jdbc-based variant assuming both are present as beans within the same Spring application context, which is often the case when component-scanning is applied liberally.
This annotation is semantically equivalent to the element's primary attribute in Spring XML.
I didn't completely follow your second question.

Spring : autowiring inside non spring class

I have this HTTP listener subclass
public class MigificSessionListener implements HttpSessionListener {
#Autowired
#Qualifier("notificationThread")
private NotificationThread notificationThread;
#Override
public void sessionDestroyed(HttpSessionEvent hse) {
// here notificationThread value is null
}
}
Value of notificationThread inside sessionDestroyed() is null.
How can i autowire sessionDestroyed inside this class ?
Your MigificSessionListener in not in your spring conext, spring even do not know it exists.
You can use WebApplicationContextUtils to get your spring context from ServletContext
WebApplicationContextUtils.getWebApplicationContext(sessionEvent.getSession().getServletContext())
You can enable Spring AOP with #EnableSpringConfigured and annotate your class with #Configurable. This let spring manage instances which are created outside the spring context with new. You will also need to enable either load-time weaving or compile-time weaving. This is documented in 9.8.1 Using AspectJ to dependency inject domain objects with Spring.
#Configuration
#EnableSpringConfigured
public class AppConfig {
}
#Configurable
public class MigificSessionListener implements HttpSessionListener {
#Autowired
#Qualifier("notificationThread")
private NotificationThread notificationThread;
//...
}
Convert your non-Spring managed class MigificSessionListener into a Spring-managed one by annotating it with #Configurable.
For this annotation to be recognised you need <context:spring-configured/> in your Spring XML config or #EnableSpringConfigured if you are using Spring Java config.
The #Autowired or injection of other dependencies will then succeed.

Use Spring #Transactional in Scala

We have a mixed Java and Scala project, which uses Spring transaction management. We are using the Spring aspects to weave the files with #Transactional annotated methods.
The problem is, that the Scala classes aren't woven with the Spring transaction aspects. How can I configure Spring to regard the transaction in Scala?
Spring needs your transaction boundary to begin with Spring-managed beans, so this precludes #Transactional Scala classes.
It sounds like the simple solution is to make service facades which are #Transactional Java classes instantiated as Spring beans. These can delegate to your Scala service/core code.
A Scala-only solution is to use Eberhard Wolff's closure that creates a manual transaction. Usage:
transactional() {
// do stuff in transaction
}
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionManagement.scala
https://github.com/ewolff/scala-spring/blob/master/src/main/scala/de/adesso/scalaspring/tx/TransactionAttributeWithRollbackRules.scala
Found here: http://www.slideshare.net/ewolff/scala-and-spring (slide 41)
License: Apache
There is nothing special about Spring's #Transactional support in Scala and you can use it without any Java code. Just make sure that you have "pure" traits for beans, which implementations would use #Transactional annotation. You should also declare a bean with PlatformTransactionManager type (if you are using .xml-based Spring configuration, you should use "transactionManager" for bean name, see EnableTransactionManagement's JavaDoc for details). Also, if you are using annotation-based configuration classes, be sure that these classes are placed in their own dedicated files, i.e. don't place any other classes (companion object is OK) in the same file. Here is simple working example:
SomeService.scala:
trait SomeService {
def someMethod()
}
// it is safe to place impl in the same file, but still avoid doing it
class SomeServiceImpl extends SomeService {
#Transactional
def someMethod() {
// method body will be executed in transactional context
}
}
AppConfiguration.scala:
#Configuration
#EnableTransactionManagement
class AppConfiguration {
#Bean
def transactionManager(): PlatformTransactionManager = {
// bean with PlatformTransactionManager type is required
}
#Bean
def someService(): SomeService = {
// someService bean will be proxied with transaction support
new SomeServiceImpl
}
}
// companion object is OK here
object AppConfiguration {
// maybe some helper methods
}
// but DO NOT place any other trait/class/object in this file, otherwise Spring will behave incorrectly!

Resources