In Spring DI, we can bind an interface with an instance programmatically as below:
#Bean
public MyService getMyService() {
return new MyService1();
}
Is there a way to bind the interface with MyService1.class instead? I do not want to create the instance myself.
You can annotate your MyService1 class with #Service (or #Component, #Repository and others...).
This way, when you inject a MyService interface, it will automatically look for existing implementations and find MyService1.
Note that your Spring configuration must contain component scanning or equivalent.
NB : if you have multiple implementations of your interface, you can use #Qualifiers.
Related
I'm wiring a third party library into a Spring Boot application and I'd like to both control its lifecycle and benefit from exception transform/translation capability of #Repository.
I can inherit from the type in the third party library and use #Repository on the inherited type, but that would not work for final classes and I want the lifecycle flexibility of #bean.
Is there any way I can declare a bean to also act like a stereotype?
As far as I know there's no way you can add stereotype information to an existing class. There's a workaround as seen in this SO answer, however it seems kind of complicated.
I'd suggest a more straightfoward approach: favor composition over inheritance. This way you can create your own class that wraps the third party library class functionality, annotate it as #Repository and define it as a ´#Bean´:
#Repository
public class LibWrapper {
private TrirdPartyClass wrapped;
public void insert() {
wrappped.insert();
}
}
#Configuration
public class LibWrapperConfiguration {
#Bean
public LibWrapper libWrapper(){
return new LibWrapper();
}
}
I currently have code laid out which looks like this:
interface strategy {}
interface repository {}
class typeOneStrategy implements strategy {
List<repository> repositoryList;
}
class typeTwoStrategy implements strategy {
List<repository> repositoryList;
}
class typeOneRepository implements repository {}
class typeTwoRepository implements repository {}
and so on.
I'd like to use Spring's autowiring to inject typeOneRepository into typeOneStrategy but typeTwoRepository should not be injected and instead only be injected for typeTwoStrategy.
Is this possible to achieve with Spring's DI?
Actually, within each #Configuration, you can define properties which are #Autowired and have #Qualifier.
By using these, you can build named beans to define inputs to strategies per the example.
However, I don't consider this to be a very efficient approach?
I'm new to spring, but not new to java.
I'd like to create base class for all REST services that would send notification through some messaging protocol on requests with chosen methods (POST, PUT, PACTCH) (when resource is changed basically)
So for example If I would create interface
public interface RestService<T, I> {
T get(I id);
T create();
T patch(I id);
T put(I id);
}
How can I use that in spring RestController and somehow decorate it with notifications?
All this spring #Autowire and configuration files is somewhat confusing to me, because while I'm familiar with dependency injection and used constructor dependency injection I haven't used IOC much.
I believe that the best option for you will be to use Spring AOP and put some annotation to the required methods. Please check this:
http://docs.spring.io/spring/docs/current/spring-framework-reference/html/aop.html
You can use any interface or base class for any restcontroller or for any other Spring stereotype. The annotations are just clues for Spring itself to use the class as an endpoint for a rest service for example. Your class otherwise can be anything, like:
#RestController
class MyController {
#Autowired
private MyService myService; //If you use the spring sterotypes you dont need to do anything to use a bean but just to use the autowired annotation
}
#RestController
class AnyotherController extends AbstractController {...}
#RestController
class YetAnotherController extends AbstractController implements Something {}
Are all valid resources (i.e. web-components) for Spring to use.
I am working on a core java framework. I don't want to create instances directly inside the class which is why I want to use dependency injection.
I am thinking of declaring my custom annotations on the fields to be instantiated. And having a call back function which would create an instance and inject it into the field.
I had tried to create a custom annotation. But looks like there's no direct way to get a callback on the declared annotation. So, I was trying to scan the classes for that. But I ended up with this problem
Java Scanning Class for Annotation using Google Reflections
Please let me know if this is the right way of achieving this.
Since your question is tagged 'Spring', you can use Spring Framework's bean annotations (#Component / #Service / #Repository / ...), classpath scanning and #Autowired.
For example:
Setup classpath scanning on your spring config xml:
<context:component-scan base-package="com.mycompany.myapp" />
Create your bean to be scanned. Spring container will automatically create a singleton instance of this bean using default constructor:
#Repository
public class FooDAO {
...
}
Inject reference to above DAO instance using DI + autowiring
#Service
public class FooService {
#Autowired private FooDAO fooDAO;
...
}
We have a framework built on top of spring and we would like to give devs the ability to override our default beans. So in a case of our "custom themer", (I wish we didn't have a custom themer) we have an interface that we autowire into the theme bean.
How can we give the user the ability to implement the same interface and we have that bean autowired into our themer class instead of our default on. Lets say the interface was call NLSER and our default implementation was NLSERConcrete, how can the end user/developer inject CustomerNLSER instead?
Use the #Primary annotation or primary="true" bean attribute in XML. This is your default bean:
#Service
public class NLSERConcrete implements NLSER {//...
//...in different class
#Autowired
private NLSER nlser;
Now if the developer adds:
#Service
#Primary
public class CustomerNLSER implements NLSER {//...
to the CLASSPATH and Spring picks it up, it will be preferred in the process of autowiring.