I've created a pojo class A(which is basically neither a service nor repository) and I want to inject it to another pojo class B, and this pojo class B I'll inject to a service class later.
Can you tell me what annotation should I mark to class A, so that it will be treated as spring bean and it could be autowired to class B
I know one annotation #Component but I'm not sure if this would be good practice to use this annotation in spring boot.
#Component is the base annotation and it's perfectly fine to use it.
#Service is only as specialization without any behavior and #Repository is used for Data access and #Controller for web.
Related
I am trying to add control authorization in some methods using
#PreAuthorize("hasRole('ADMIN')").
Methods belong to a simple class DaoImpl implementing an interface DAO,
I add this
#EnableGlobalMethodSecurity(prePostEnabled = true, securedEnabled = true)
to my security config class.
for me it doesn't work, is it logic or I miss something?
The answer is no.
Spring can only enforce annotations on classes it is aware of. To make spring aware of instantiated classes it needs to either instantiate them itself, which means the class needs to be annotated with one of springs lifecycle annotations ex. #Component, #Service #RestController, or you need to instantiate them yourself and hand them over to the spring context. This can for instance be done by using the new keyword in a #Bean annotated function in a #Configuration annotated class and then return the newly created class from the #Bean annotated function.
If you create the class yourself by using the new keyword just randomly in your application, spring will have no awareness of the class and hence has no ability to intercept function calls using spring AOP and in turn enforce annotations on them like for instance #PreAuthorize
For example, I have interface IRobot and I have an implementation RobotImpl. If I put annotation #Component on the interface will spring scan all it`s implementations? I think that annotation #Component is like saying "Hey Spring, create me an instance of this class and put it into your context so I could Autowire it later.", am I right?
Currently I use #Component only on my Views, Controllers and Models.
To be accurate, I use #RestController for Views, #Service for Controllers and #Component for Models (because I want to use Hibernate as an ORM provider)
My problem is that I also use #Autowired constructors which means that I can use only #Component based Objects in my constructor.
Sometimes I need to create a Controller that takes none-Component class. As an example - to add Config clas besides other #Component objects to my constructor .
What should I do in general:
1) Add #Component annotation to all Java classes.
2) Add #Component only to those classes that I need ? (which means that some my Config classes will have #Component when others Config classes will not.)
3) Not use #Autowired in situations like this, create a Controller in a regular way ?
4) Not use #Autowired constructors at all ?
5) Other ideas ?
I'm migrating code from JEE to SpringBoot. I was using cool dynamic injection in JEE with javax.enterprise.inject.Instance class:
Just annotating:
#Inject
private Instance<CCIntentHandler> allMycandidates;
Will make allMycandidates be filled with all classes inheriting CCIntentHandler interface in my classpath which then I can iterate simply with:
Iterator<CCIntentHandler> iterator = allMycandidates.iterator()
Nothing more needed. How can I achieve this in Spring Boot?
Thanks
Spring will inject all instances of Foo if you #Autowire a List<Foo>.
So, the Spring equivalent of ...
#Inject
private Instance<CCIntentHandler> allMycandidates;
... is:
#Autowire
private List<CCIntentHandler> allMycandidates;
Update 1 in response to this comment:
Do CCIntentHandler interface or classes implementing this interface need any Spring annotations?
Spring must be aware of any instances of CCIntentHandler, this could achieved as follows:
Annotate each class implementing CCIntentHandler with #Component and ensure that these classes are scanned by Spring Boot
Or
Provide a public method to return each class implementing CCIntentHandler and annotate each of these public methods with #Bean and ensure that the class which contains these public methods is annotated with #Configuration and that this configuration class is scanned by Spring Boot.
More details on bean declaration and dependency injection in the docs.
Unfortunately
#Autowire
private List<CCIntentHandler> allMycandidates;
is not
#Inject
private Instance<CCIntentHandler> allMycandidates;
because we can't select an instance from the list depending on type or annotation.
I've spent some time to find alternative in Spring, but looks like there is no equivalent...
We should defenetly bring that feature to Spring!
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;
...
}