Hy,
How #Autowired works in an attribute declared in an abstract class if its not inherited in the subclasses. What spring does under the hood in order the subclasses have the dependency injected in them if #Autowired annotation is not inherited in the subclasses?
Thanks
There's no such thing as a not inherited field in subclasses in Java. The private fields get inherited just as any other non-static field, they're just not visible in the subclass code. They can still be accessed with reflection though. Spring will have no problem autowiring such fields.
Related
#Autowired
UserService userService;
What happens exactly inside `#Autowired annotation whether it uses Constructor Injection or Setter Injection. I know that it is field Injection.
I'm not asking How IOC or DI works, I'm asking How Field Injection in Spring Boot works internally?
Basically field inject is a type of injection (obviously), so Spring injects dependency based on field type and maybe some annotations (like #Qualifier).
How does it work?
When Spring creates a bean, there is a special Bean Post Processor org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
Each field marked with #Autowired is considered by spring as a dependency, so it must analyze these dependencies (by using reflection under the hood) and find a match from the application context for each field (by Type, qualifier if specified, etc.). Then it sets the value, right into the field, again by reflection.
I don't intend to start "holly-wars" here, but I'll just mention that I personally try to avoid using this type of injection because it effectively breaks encapsulation of dependencies, making the class with autowired fields non-unit testable.
For example if you have something like this:
#Component
class Foo {
#Autowired
private Bar bar;
public Foo() {} // no-arg construction that exists by default
}
#Component
class Bar {
}
Then when you create an instance of Foo by yourself (e.g. in unit-test) you have no clear way to supply the Bar dependency to Foo instance without relying on spring.
Constructor Injection solves this for example.
I have a mapper class for an incoming Event message.
Once the event message comes to the application, the mapper class sets the values in the entity object and saves it in the Database.
I have Autowired the entity object in my mapper class.
Whenever a new event comes in, the autowired entity object is still having the Old/previous values.
Is autowiring of Domain/Entity object possible in this case or I should go with 'New' keyword instead of Autowiring as Spring bean.
I see some posts about using #Configurable. I am not sure which is the best coding practice in this case?
#Service
public class LegacyEventMapper {
#Autowired
private LegacyEvent legacyEvent;
#Autowired
private LegacyEntity legacyEntity;
public void mapLegacyNotificationDetails(LegacyScheduleEvent body) throws Exception {
//Setting the values into the Entity object
Thanks
I have no idea why you actually want to #Autowire an #Entity and make it spring aware. This is wrong. You can do it, but it makes absolutely no sense.
What you actually want to do is create a new LegacyEntity (via the new LegacyEntity) and save that instance to DB.
What you have read via #Configurable is the other way around - you inject a spring bean/service into an Entity.
I think We can #Autowire an #Entity class. But then we need to mention in Entity class that it is of Request scope
#Entity
#Scope(scopeName=WebApplicationContext.SCOPE_REQUEST, proxyMode=ScopedProxyMode.TARGET_CLASS)
public class LegacyEntity {
I am not sure if using the new keyword is the better approach instead of autowiring an Entity class?
From spring reference doc
Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the #Transactional annotation, as opposed to annotating interfaces. You certainly can place the #Transactional annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java
annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the transaction settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a transactional proxy, which would be decidedly bad.
Though it only talks about interfaces, abstract classes are considered as non-concrete as well.
So if i have an abstract class
public abstract class BaseService{
//here is a concrete method
#Transactional
public void updateData{
//do stuff using dao layer
}
and a concrete class which extends the class
public class SpecialService extends BaseService{
//body of class
}
Now if i call specialService.updateData() from my controller class will it be transactional?
Granting that you have actually configured Spring transaction management correctly, using #Transactional on an abstract superclass will work, since #Transactional is itself annotated with #Inherited and from it's Javadoc we have:
Indicates that an annotation type is automatically inherited. If an
Inherited meta-annotation is present on an annotation type
declaration, and the user queries the annotation type on a class
declaration, and the class declaration has no annotation for this
type, then the class's superclass will automatically be queried for
the annotation type. This process will be repeated until an annotation
for this type is found, or the top of the class hierarchy (Object) is
reached. If no superclass has an annotation for this type, then the
query will indicate that the class in question has no such annotation.
Note that this meta-annotation type has no effect if the annotated
type is used to annotate anything other than a class. Note also that
this meta-annotation only causes annotations to be inherited from
superclasses; annotations on implemented interfaces have no effect.
To actually see that #Transactional is annotated with #Inherited check out it's Javadoc
I'm using spring mvc 3.1.x and jets3t.
I have a DataAccessObject that i instantiate as a Singleton bean..
I managed to get it working through extending the applicationcontextloader class and adding it to the web.xml
EDIT:
I changed my method, I tried inject and autowired but it's not suitable for my needs.
What I've done was to implement ApplicationContextAware and set it up as a bean, in the code I use it as follows:
ApplicationContext ctx = BannerApplicationContext.getApplicationContext();
BannerGenericDAO bdao = (BannerGenericDAO) ctx.getBean("dao");
I'm new to Spring and in general the servlet world..
Questions are:
what's the best way of doing this? Is this considered a "best-practice"?
How do you inject an object, keeping other method fields that are not supplied by autowiring?
How do you get an object to be used throughout the entire application?
Thanks!!
You could use annotations in your controller.
#Controller
public class MyController{
#Autowired // or #Inject, which is more JEEish (JSR330).
private SomeDao daoService;
}
Given "SomeDao" is the type of your singleton DAO, of course.
On many tutorial/books about spring JDBC, RowMapper class usually represented as private static final class inside DAO and the instance is created in every single query.
Does RowMapper have to be used and instantiate in this way?
Is it ok if I define RowMapper class as spring bean using #Component annotation and #Autowired it to my dao class?
Which one is better?
Does RowMapper have to be used and instantiate in this way
No, that's just a common usage pattern.
Is it ok if I define RowMapper class as spring bean using #Component annotation and #Autowired it to my dao class?
Sure, that would work. Unless the RowMapper needs access to other Spring services, though, there's not much point.
Which one is better?
Without seeing your code and getting a feel for your application, we can't really tell you if it's a good idea or not, only you can make that choice.
My personal preference would be to keep the RowMapper as a non-static inner class of your DAO class, and to insantiate it directly from the DAO. If the RowMapper needs access to other Spring beans, then wire those intop the DAO, and access them from the RowMapper inner class.