I have a recurring annotation in my app that's injecting an object created by a CDI-producer.
#Inject
#FlatGeometryLive
FlatGeometry geoObject;
I wonder if it's possible to write a stereotype "#FlatGeometryLiveInject" so that i only have to write
#FlatGeometryLiveInject
FlatGeometry geoObject;
and the object is injected.
Is this possible with CDI 1.1 or any DI framework?
I don't think it's possible, because the frameworks you are using are aware, in specific point of their code, of annotations which name is Inject and FlatGeometryLive. If you define a new annotation how those frameworks could be aware, and act consequently, of your new created annotation?
In order to improve your writing productivity it's better you use your favorite IDE's hints or templates: you might create a shortcut for the text aif (Annotate with Inject and FlatGeometryLive) that your IDE will expand.
Related
From a software design perspective, when should we use #Component instead of a traditional Java class (that needs to be explicitly instantiated by 'new')? For example, if we need to create a class that is one of the following patterns:
Adapter
Bridge
Façade
Strategy
Translator
Should the class have the #Component annotation (or any Spring derivative annotation such as #Repository/#Controller/#Service)?
Spring applies the Inversion of Control principle, which drills down to that the framework handles stuff for you, so you don't have to worry about it.
By using #Component on the class you let Spring create a bean for you.
This way Spring can, for example, inject this bean on runtime when you need it. (For example by Autowiring your constructor).
It is up to you to decide if you want to make use of this functionality for your class. A facade for example could very well be a Spring component, this way you could possibly inject an API implementation that is exposed via a facade on runtime, without the need to think about the dependency injection implementation.
I would not recommend using this annotation on a DTO or model class for example. These classes mostly consist of data and don't fit the need to be managed by Spring.
Other interesting related questions that can help you decide when to create a component:
What's the difference between #Component, #Repository & #Service annotations in Spring?
Spring: #Component versus #Bean
Is there any way (existing framework) to configure DI in Java without having to add annotations to classes where they "don't belong"?
In my research, it looks like to accomplish constructor injection we need to add some annotation to the constructor, like this:
#Inject // or #Autowired for Spring Boot
public MyInjectedClass(IThing1 thing1, IThing2 thing2) { ... }
Spring Boot also suggests adding #Service to implementations in order to register them with DI for injection.
Adding these annotations brings DI into the injected class (MyInjectedClass and any controllers, service implementations, etc.). Those classes should have no concept of DI, they should just be given the things they ask for in the constructor and not care about how they got there.
I know you can use the #Configuration attribute in Spring Boot, but this still feels not very configurable or powerful. Is there any way to accomplish this using Java without annotations? E.g. like how SimpleInjector, AutoFac, etc. work in C#? (Configured via code, not XML or config files, and not via annotations.)
If not, I'm curious why such a different approach has been taken between Java and C# in regard to DI.
Update I've offended someone in the comments but that was not my intent at all. I am asking a legitimate question. Let me highlight my concern/question in another way.
Suppose I have the following packages/classes. I have marked each case where each type of DI will appear. By "appear" I mean these marked classes/packages have some relation to the DI framework being used.
[A]: annotation-based DI (3rd party package dependency)
[C]: configuration-based DI
data_access [A]
repositories
PersonRepository [A]
logic [A]
people
CreatePersonCommandHandler [A]
UpdatePersonCommandHandler [A]
services [A] [C]
controllers
PersonController [A] [C]
I hope this helps to illustrate my true question. The footprint of annotation-based DI extends into the far reaches of the stack, whereas configuration-based DI is only used in the outermost (entry) application, where the composition root lives.
This question already has answers here:
#Resource vs #Autowired
(11 answers)
Closed 6 years ago.
I have recently started using Spring framework. I'm confused between when to use #Resource vs Property argument in xml file (the traditional way). What are the special real use-cases that were considered for designing new Annotations ? Would you advice to shift completely to using Spring Annotations ?
Well the difference between #Resource and #Autowired is already well explained by a lot of posts, you could also find from my blog.
Basically they are specifying different way to search for a bean before Injection.
#Autowired will assembled by type before by name in default, whereas #Resource assembled by name in default then type. They also belong to different jar.
Regarding Property argument in xml file, it is the way you specifying the value of fields in beans. Say you want to create a bean named SamplePerson which is an object of a Person Class, what you need to do in xml is to tell Spring what the value of field in this object, just like:
Person samplePerson = new Person();
samplePerson.setAge(23);
samplePerson.setName("Rugal");
After creating such a bean, Spring context will place this object inside its container for later usage. Now you could use #Autowired or #Resource to inject this samplePerson bean into a place where needed by using
#Autowired
private Person samplePerson;
Then you will notice this person object will have its attributes corresponding to your xml definition.
But actually it is tedious to code under XML, I would rather to do all the configuration in Java style, although somebody might argue it is not dynamic enough.
Yes you could totally switch everything from XML configuration to Java configuration. You could get my sample from github.
If you are new to Spring, I will encourage you to use my archetype. You will get a fully integrated code base.
#Autowired is a Spring-specific and #Resource is JSR but current Spring supports both of them. I'd use the JSR one because it will work also without Spring framework so less changes if you decided to use something else).
Regarding the annotations vs XML please refer this question Spring annotation-based DI vs xml configuration?
It depends on use cases. For me annotations are easier because they allow to keep everything directly in the java code so it's just self-documenting. But sometimes you may want to use XML (for example if you want to change your configuration without modifying the code itself you can easily switch between different xml locations)
How would you extract something prior 2.5 version from .xml config? It bothers me because if #Autowired is removed from my arsenal I would not really know what to do.
Say I want to use some DAO implementation.
In service class I usually write:
#Autowired
someDaoInterface generalDao;
Then I typically call
generalDao.someInterfaceMethod(someParam param);
How would I extract implementation from config in Spring 2.0 to use this method?
Is it as dumb as just: new ApplicationContext(pathToXml) and then use .getBean or there is other way?
Why do I ask for taking bean out from configuration file?
Because in Spring MVC how can you perform your logic without getting beans out from the application context.
If you have #Controller handler then you need to make calls to the service classes' methods? So they should be somehow retrieved from the context and the only way so far is using #Autowired? Then I would also want to populate Service classes as I stated in previous example with DAO classes and they also need to be retrieved from the application context, so I would be able to write logic for service classes themself. How would people do it in the past?
I see the #Autowired as the only mean of taking something out, not because it is convenient to wire automatically - I am perfectly ok with XML.
You still have option to wire it explicitely via property or constructor parameter. (Anyway, autowired is not going to work if there is ambiguity in your container )
Of course, you can use application context and getBean() in your java code, but it violates DI pattern and makes all the spring stuff useless. Purpose of DI is to decouple your business loginc from implementation details - it's not business logic it's how and where it dependencies come from. Dependencies are just there.
By using ApplicationContext.getBean() you are breaking this pattern, and introduce dependency to:
spring itself
your configuration names
After you done this, you can as well drop use of DI and spring because you just voided all the advandages DI is providing to you. (BTW, #Autowired also introduces dependency to spring, and violates DI pattern, it also implies that there is only one instance available)
Also, answer is: in ideal case there shall be no reference to spring in your code at all.
No imports, no annotations - just interfaces of collaborating entities.
Can an annotated Spring MVC Controller also be annotated with #Component/#Service type of annotations and be used both as a controller and as a bean?
Edit: placing more emphasis on the software design aspect, and updating the API link to SpringV3
As mentioned in other answers, this is not an ideal approach to Spring MVC, but nevertheless the controller will already be available for autowiring in your ApplicationContext.
It's already a Bean in your ApplicationContext, so you can auto-wire it by type. There's no need to add an #Component annotation.
From the Spring API Docs: "This annotation serves as a specialization of #Component, allowing for implementation classes to be autodetected through classpath scanning."
http://static.springsource.org/spring/docs/3.0.x/api/org/springframework/stereotype/Controller.html
The same holds true for #Service.
Although I've done it myself, I would not normally recommend this design approach.
If possible, refactor the required functionality into a separate bean, which can then be (auto-)wired into both the #Controller, and any other bean, as required.
If, as you have commented, you are 'cornered' into this decision (as I was, by previous design choices), then so be it.
HTH
It can but it shouldn't. A web controller should be an entry point, nothing else.
Any reusable logic it performs should be in a dedicated service layer, not in the controller itself
No, sounds like it's doing too much. One or the other, not both. I don't know if it's possible (I doubt it), but I'm sure it's not advisable.
I think that you should hear more about patterns like Front Controller, MVC, DAO and Multitier architecture and so on.