I know that you can use the annotation #Mapper(componentModel = “spring”) to use Spring to manage/inject the mapper dependency. My question is, are there any advantages to this approach vs declaring an instance variable within the mapper class itself:
#Mapper
public interface SomeMapper {
SomeMapper INSTANCE = Mappers.getMapper(SomeMapper.class);
SomethingElse mapSomethingToSomethingElse(Something something);
}
...
// Clients using mapper
SomethingElse result = SomeMapper.INSTANCE.mapSomethingToSomethingElse(input);
When using Spring dependency injection to inject mappers, you will end up adding extra constructor arguments/instance fields which is desirable as it makes it more obvious that a class is starting to rely on too many dependencies and should most likely be refactored (eg. think about Sonar's rule 'Too many parameters').
Another advantage is that since you're registering the mappers as beans in the Spring context, you can leverage the framework capabilities to easily inject dependencies in your mappers, customize all mappers at runtime through the BeanFactoryPostProcessor and rely on all the other framework abstractions that seem fit.
I'd say since you're already using Spring in your application, there is pretty much no reason to not register the mappers as Spring beans and inject them the DI way rather than turning them into static utils.
Related
I am working on a Spring MVC project where I am dealing with different types of services,Repositories i.e classes annotated with #Service and #Repository. I am confused with a couple of questions:
When to use #AutoWired annotation?
I have seen various repositories using this:
CourseRepository crepo=new CourseRepository();
and I have seen this also
#AutoWired
private CourseRepository crepo;
Which one of the above options should be used to get an instance of
repository in Service class?
Can I use #AutoWired for classes which are not annotated with #Repository or
#Service?
I am a beginner in this java world.Any help will be highly appreciated.
Thanks
You use new for data objects, which in most modern architectures are passive (they're not "active records"). Everything else is a service object, and you should inject those. (The one place that you do use new is with an #Bean method, which is a "factory" that creates the service object; in this case you normally pass the dependencies as method parameters.)
Note that it is recommended to use constructor injection instead of field injection; it makes your code easier to test, and it eliminates the possibility of certain kinds of errors. In fact, if using constructor injection, it's not required to have any Spring annotations in your service classes at all; beans can be registered using #Import instructions or #Bean methods on a configuration class.
You should #Autowire the dependencies instead of instantiating it yourself. Doing so, service and repo layer will be loosely coupled. Moreover, a mock repository can be easily injected in service's JUnit test class if dependency is autowired. To conclude, use below:
#Autowired
private CourseRepository crepo;
A class not annotated with any of below stereotype annotations will not be in Spring's IoC (Inversion of Control) container. Hence, no point in autowiring in a class that is not annotated with any of below annotations.
#Component, #Controller, #Service, #Repository
Dependency injection means that the framework is the one who handles the classes instantiation and the object of that class is going to be injected (thanks to #Autowired annotation) in the class where you need it. In other words, you do not need to instantiate service and repository classes by yourself using new operator, you just need to tell the framework that those classes need to be injected and that's why you use #Autowired annotation.
I want to define a annotation like #PlatformRelated, once it is marked in a interface, there will be a proxy bean at spring context, and this proxy bean should be #Priority.I want this proxy could invoke different implement according to key parameter #KeyPrameter.And I still wanna use spring features like #Async,#Trasaction,etc... at my Implement1 and Implement2.
#PlatformRelated
interface MyInterface {
method(#KeyPrameter String parameter);
}
#Component
class Implement1 implements MyInterface {
method(String parameter){
//do something 111
}
}
#Component
class Implement2 implements MyInterface {
method(String parameter){
//do something 222
}
}
#Service
class BusinessService{
#Autowired
private MyInterface myInterface;
public void doSomething() {
myInterface.method("key1");
//Implement1 work
myInterface.method("key2");
//Implement2 work
}
}
Do you guys have some good idea to complete it?
I must admit I haven't totally understood the meaning #Priority, however, I can say that if you want to implement this feature in spring, you should probably take a look at Bean Post Processors.
BeanPostProcessors are essentially a hook to Bean Creation process in spring intended for altering bean behavior.
Among other things, they allow wrapping the underlying bean into the proxy (CGLIB/java.lang.Proxy if you're working with interfaces, or even using programmatically Spring AOP), these proxies can provide a hook to the method execution that can read your annotations (like mentioned #KeyParameter) and execute a code in a way similar to Aspect's code that you already make use of.
Not all bean post processor wrap the bean into the proxy. For example, if you want to implement a BPP that uses "#Autowire", you will return the same bean, just "inject" (read, put by reflection) its dependencies. On the other hand, if you want to implement with BPP #Transactional behavior, then yes, you should wrap the bean into a proxy that would take care of transaction management capabilities before and after the method execution.
It's totally ok to have a spring bean that gets "altered" by many post processors, some of them would wrap it into a proxy other will just modify-and-return the same bean, If there are many BPP-s that wrap the bean into proxy we'll get "proxy inside proxy inside proxy" (you get the idea). Each layer of proxy will handle one specific behavior.
As an example, I suggest you take a look at existing Spring postprocessors, or, for instance, a source code of the following library: Spring Boot metering integration library
This library contains some implementations of post processors that allow metrics infrastructure integration by defining annotations on methods of Spring Beans.
I am looking into a codebase where every POJO has been managed by spring and injected using lookup annotation.
#Lookup
public Publisher getPublisher() {
return new Publisher();
}
#Lookup
public Book getBook() {
return new Book();
}
These Publisher and Book objects are nothing but POJO with just getter/setters. These classes are spring managed as prototype beans. I am thinking, it is over use of lookup annotation and overhead where we could just use factory methods or simply create new instance. Do you think using lookup annotation for this use case useful/efficient?
In a general way, making instances of a class some spring beans is not relevant if these beans never be needed to take advantage of Spring features and if these beans never be injected in other beans or never needs to inject other beans in their own instance.
#Lookup is the annotation-based way of the the old XML lookup-method attribute. Besides beans created with this annotation also have multiple limitations. For new projects I never use it.
As alternative as you need to declare beans in the java class the #Bean annotation that creates "not limited" beans should generally be favored instead of.
EDIT :
I wrote an answer to a very related question yesterday : Spring - is using new a bad practice?.
I just updated it to be more exhaustive.
I'm trying more and more to design and build my applications such that they are framework agnostic. This means using JSR annotations instead of Spring annotations, JPA2 interfaces, etc. but I find myself having a lot of difficulty at times.
For example, at the moment, I need to retrieve a list of all beans of a particular class. Using a Spring-specific method, I can use the ApplicationContext to .getBeansOfType(Clazz), but I'm trying to do this without using the Spring ApplicationContext.
Is there a JSR equivalent to Spring's application context?
Ex (quick psuedo code):
#Autowired private ApplicationContext ctx;
protected Map<String, Clazz> getBeans(){
return ctx.getBeansOfType( Clazz );
}
How can I do this without using Spring?
I think that not.
For Spring, you could use:
#Inject
private Map<String, Foo> fooBeans;
to avoid explicit reference to ApplicationContex, but AFAIK this will not work with others DI containers.
You won't find a framework agnostic way of doing this. For CDI you'd use
#Inject
Instance<Foo> fooBeans;
I'm learning Spring and looking at using Spring Test for my web app (JQuery/CXF/Hibernate). I have been using annotations to wire up my beans and noticed that this sometimes got into the way of polymorphism. For example I have a GenericDAO extended by all DAOs. It is also a concrete class used by simple services, so when I wired it for one of those services, ALL other DAOs became candidates for runtime wiring (because of polymorphism). I could solve that by wiring explicitly by type: #Resource(type= GenericDaoImpl.class), but this goes against the best practice of coding to interfaces ..
Now I want to create unit tests using a MockGenericDaoImpl, and integration tests using GenericDaoImpl. How will I override the annotations? I'm guessing the best approach is to stick to XML-based wiring, so that I can have several versions of beans.xml, one for prod, one for unit tests, one for integration tests, and possibly split them into parallel sub-files, as needed. Isn't this approach more flexible than depending on annotations that either scan to guess the appropriate candidate, or constrain polymorphism?
Can someone give me broad directions on how to organize my test configuration setup? Thank you!
How about using #Configuration class? If you're not familiar with this method - you can declare a class that replaces the XML context file and looks something like this:
#Configuration
#ComponentScan({ "com.project.dao"})
public class TestConfiguration {
#Bean
public GenericDao getGenericDao() {
return new MockGenericDaoImpl();
}
}
In the #ComponentScan annotation just put the relevant packages to scan. This way you're very flexible with the beans you're creating and the way to create them. You can injects mock to the beans whatever way you'd like.
Also you can create several test configurations, each configuration for a different purpose. In order to load the context you need to put this annotation on your test class:
#ContextConfiguration(classes={TestConfiguration .class})
Using XML configuration files prevent you from depending on Spring dependencies. You can replace it with another DI framework(maybe Guice, but this is not realistic for big projects I know). Using XML configuration files enables you to code cleanly.
I hate XML but I hate existence of not-business-logic-specific things in my code more.
I see you know how to overcome the test issues using XML configuration files. I will try to show how to overcome duplication of implementations(one real one mock implementation) problems using annotations.
You can define your beans via annotations. You can select implementation using aliases:
project.dev.properties:
my.project.dao.xDao=xDaoJpaBean
project.test.properties:
my.project.dao.xDao=xDaoMockBean
<alias name="${my.project.dao.xDao}" alias="xDao"/>
#Autowired
#Qualifier("xDao")
protected XDao xDao;
So you can select your implementation just using your properties file. If you want to use Annotations purely you can do this as well:
#Autowired
#Qualifier("${my.project.dao.xDao}")
protected XDao xDao;
Your build environment will specify which properties file to load, in return your bean will be assigned.