got declared spring beans in an other spring bean - java

#Component
public class IServiceCollection {
#Resource
private IService service1;
#Resource
private IService service2;
#Resource
private IService service3;
#Resource
private IService service4;
#Resource
private IService service5;
public List<IService> getAllServices(){
List<IService> iServiceList = new ArrayList<IService>();
iServiceList.add(service1);
iServiceList.add(service2);
return iServiceList;
}
}
in IServiceCollection I will refer lots of IService beans like service1, servvice2, etc. I wanna get all of the service beans in method getAllServices().
How can I add all the services to the list automatically, not like the code above?

You have a few options:
.1. If you inject in a map this way:
#Component
public class IServiceCollection {
#Autowired
private Map<String, IService> services;
that would inject in all implementations of IService with the key of the map being the bean name
.2. You can inject in a list this way:
#Component
public class IServiceCollection {
#Autowired
private List<IService> services;
again you would have a list of IService instances.

Related

Intellij Idea Structural Replacement (replacing autowired annotation)

I wonder whether it's possible to replace all the Autowired fields with final ones and #RequiredArgsConstructor below the class declaration?
For instance, replace the following code
public class Controller {
#Autowired
private Reposiroty repository;
#Autowired
private Service service;
...
}
with something like that:
#RequiredArgsConstructor
public class Controller {
private final Reposiroty repository;
private final Service service;
...
}
Thanks in advance!

UnsatisfiedDependencyException with REST service

I am trying to create some unit tests for my REST API service class. This service class implements a service interface. However, when I try to run my tests I get this error:
org.springFramework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dev.x.y.unit.ContactServiceImplTest': Unsatisfied dependency expressed through field 'contactServiceImpl';
My test class:
#ExtendWith(SpringExtension.class)
class ContactServiceImplTest {
#MockBean
private ContactRepository contactRepository;
#Autowired
private ContactServiceImpl contactServiceImpl;
...
my contactServiceImpl implements from my ContactService, I have tried annotating with #Component and #Service, but I am still receiving the same error.
ContactServiceImpl class:
#Service
#Transactional
public class ContactServiceImpl implements ContactService {
Logger logger = LoggerFactory.getLogger(ContactServiceImpl.class);
#Autowired
private final ContactRepository contactRepository;
....
My interface:
#Service
public interface ContactService { ... }
Any advice would be amazing.

Spring - How to inject String value to constructor?

I have following component:
#Component
public class ServiceManagerImpl implements ServiceManager {
private final ServiceA serviceA;
private final ServiceB serviceB;
private final String path;
#Autowired
protected ServiceManagerImpl(ServiceA serviceA, ServiceB serviceB, String path) {
this.serviceA= serviceA;
this.serviceB= serviceB;
this.path= path;
}
(...)
}
Now I want to create simple service to which I will inject above component with specific path value. This value should come from class with String constans:
#Component
public class ServiceManagerClientImpl implements ServiceManagerClient {
private ServiceManager serviceManager;
#Autowired
public ServiceManagerClientImpl(ServiceManager serviceManager) {
this.serviceManager = serviceManager;
}
}
Is it possible to dynamically inject simple path values on ServiceManagerClientImpl level (not from properties / yaml files)?
You can autowire the Environment class
import org.springframework.core.env.Environment;
#Autowired
private Environment environment;
You can read the enironment variable("path" in your case) using the below statement.
environment.getProperty("path");

Spring - Autowire Service into POJO

I have a model in which I want to inject my service.
My Model
#Configurable
#Entity
#Table(name = "user")
public Class User {
#Autowired
private UserService userService;
{
System.out.println("Trying Service : " + userService.getMyName());
}
}
Here I get always a NullPointerException on 7'th line.
In my spring-context.xml I have :
<context:spring-configured/>
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
EDIT
UserService
#Component
public Class UserService {
public String getMyName() { return "it's Me!";}
}
Spring managed components can be wired only into another beans managed by Spring.
However, there is a trick to add service to your POJO if you really need it:
Add UserService as a static field to your POJO with a setter
In UserService after spring initializes the bean, set itself as a field on the POJO (this can be done in #PostConstruct method)
Make a static instance of UserService available:
#Service
public Class UserService {
private static UserService instance;
public static UserService getInstance() { return instance; }
#PostConstruct
void init() { instance = this; }
public String getMyName() { return "it's Me!";}
}
call with:
UserService.getInstance().getMyName()

CDI constructor-based injection with #Resource

Is it possible to do a constructor-based CDI injection of a #Resource type of instance?
I have the following class:
class MyClass {
#Resource
private ManagedExecutorService executorService;
#Inject
private MyService myservice;
}
I would like to convert it into something like this:
class MyClass {
private final ManagedExecutorService executorService;
private final MyService myservice;
#Inject
MyClass(ManagedExecutorService executorService, MyService myService)
{
this.executorService = executorService;
this.myService = myService;
}
}
This would make the class immutable and easier to unit test. The problem is that since the executorService needs to be obtained via a #Resource annotation, it doesn't seem to be injectable via the constructor.
Here is what I ended up doing - I created a producer class to managed the resource object:
public class ExecutorServiceProducer {
#Resource
private ManagedExecutorService managedExecutorService;
#Produces
#Managed
public ExecutorService createManagedExecutorService() {
return managedExecutorService;
}
}
and I created this custom annotation:
#Qualifier
#Retention(RUNTIME)
#Target({TYPE, METHOD, FIELD, PARAMETER})
public #interface Managed {
}
and then I was able to annotate my class as follows:
class MyClass {
private final ExecutorService executorService;
private final MyService myservice;
#Inject
MyClass(#Managed ExecutorService executorService, MyService myService)
{
this.executorService = executorService;
this.myService = myService;
}
}
This way I can unit test the class by providing my own ExecutorService (non-container managed) instance.

Categories