Why is spring’s DI/IoC considered more decoupled than just regulars OO? - spring

I’m trying to learn spring coming from a regular OO background.
In regular OO if you wanted to decouple a dependency. You would do it by
Car car = CarFactory.getCar();
where you can have BigCar and SmallCar implements Car.
In spring, the dependency is decoupled by
#Autowire
BigCar car;
Or configured via XML.
Question is how is that more decoupled? In all 3 cases, you either
Change 1 line of code in your factory
Change 1 line of code below #Autowire
Change 1 line of XML code

In spring there's a concept called Inversion of Control(IoC).
Basically it means,
Inversion of Control is a principle in software engineering by which the control of objects or portions of a program is transferred to a container or framework.
You can check it here https://www.baeldung.com/inversion-control-and-dependency-injection-in-spring
So using spring we're not creating objects where we needed but we're delegating this responsibility to the spring by just notifying where it should be created. In the above example by using #Autowired. Which is obviously loose coupled than in OO design.

Dependency injection is more decoupled because the object which wants a reference to a Car (in this example) does not need to contain any code that retrieves or creates a Car. In the case of dependency injection, the dependency injection container creates the beans, establishes the relationships and satisfies dependencies between beans.
The bean creation is completely decoupled from the code that uses the beans; it can be defined in the form of Java configuration or XML in the case of Spring.
An additional advantage is that dependency injection establishes a single mechanism to establish relationships and satisfy dependencies between beans.

Related

can anyone please tell me what is the difference between Inversion of Control (IOC) and Dependency Injection (DI) in spring?

I'am seriously figuring out this for the last one week and continuously keep on reading articles and blogs so that I can understand the difference in the very leman language and terms so that I can understand easily!!!!!
Dependency injection is simply about depending on an abstract interface and passing a concrete implementation of that interface to your class through the constructor or a setter method. This allows you to use a different concrete implementation without changing your class. This is useful, for instance for testing.
IoC is also known as the Hollywood principle: don't call us, we call you. In this case a framework defines an interface and the application provides the concrete implementation. This helps to limit dependencies between classes. IoC is often implemented using dependency injection, but it's not a hard requirement.

Object created in Spring

I would like to know, whether this is a valid practice to use "new" in spring to create a Object?
You can either use xml->bean to create a object using xml file or use annotations to create a object.
This question arises when I am working on a project and where I want to create a object of a property class(which contains properties and setter/getter method of those properties).
I am able to create a object using new and its working fine but if spring has capability to create and manage object lifecycle then which way I need to go create a object and why?
I think the confusion may arise because of the (over)usage of spring as DI mechanism. Spring is a framework providing many services. Bean or dependency injection is just on of those.
I would say that for POJOs which have just setter and getters without much logic in them you can safely create objects using new keyword. For example, in case of value objects and data classes which do not have much configuration or life cycle events to worry about, go ahead and crate those using new keyword. If you repetitively create these objects and have fields which are not changing often, then I would use spring because it will lessen some of the repetitive code and object creation can be considered externalized or separated from your object usage.
Classes instantiated using spring bean definition xml/annotations are basically 'Spring-Managed' beans which mostly means that their life cycle, scope, etc are managed by spring. Spring manages objects which are beans, which may have some life cycle methods and APIs. These beans are dependencies for the classes in which the are set. The parent objects call some API of these dependencies to fulfil some business cases.
Hope this helps.
The Dependency Injection concept in spring is more useful when we need to construct an object that depends upon many objects, because it saves you time and effort for constructing as well as instantiating dependent objects.
In your case , Since it's a POJO class with only setters and getters , I think it is absolutely safe to instantiate it using a new keyword.

Should I use dependency injection on these domain classes?

Do I use dependency injection in the following example:
#Scope("prototype")
#Component
public class Order{
#Autowired
public Order(User user,List<OrderItem> items,.......){
Now somewhere else:
#Component
public class PersistOrder{
#Autowired
Provider<Order> orderProvider;
public void prepareOrder() {
Order order = orderProvider.get();
AS JSR-330 states, the get() method of Provider returns a new instance of Order, but what objects are passed to the new order's constructor? As you can see the order has its own dependencies that has to be injected before the actual order object is retrieved to the method.
Without DI I simply create all neccessary arguments and pass them to the constructor of the new order. So should I use DI here?
EDIT:
This is what the code would seem without DI:
#Component
public class PersistOrder{
public void prepareOrder() {
User user=userDao.get(userId);
List<OrderItem> orderItems=orderItemDao.getAll(orderItemIds);
Order order = new SmartPhoneOrder(user,orderItems);
As you see I have the ids of user and order items and can get their instances from DAOs. Then I pass these instances to the constructor of a subclass of the Order to get an instance. The process seems very clear to me. I mean how can I do this work with DI so that my code enjoy decoupling between PersistOrder and Order classes? Or using DI in this example makes the logic more complex?
Without dependency injection, domain objects can be considered anaemic, and this is arguably an anti-pattern. You're losing many of the benefits of OO, by having data structures, without associated behaviors. For example, to evaluate Order.isValid() you may need to inject some dependency to perform the validation.
You can get dependency injection on classes outside the context of the Spring container by using:
#Configurable
You then declare the recipe for the bean as a protoype, and Spring will use AOP to swizzle the constructor and look up the required dependencies. . Even though its looking up the dependencies, the net effect for you is dependency injection, because you'd only have to change one line to inject something else that evaluates Order.isValid().
This way when you do new Order, or get it from you persistence factory, it already has the dependencies "injected".
To do this requires aspectJ weaving and not just Proxy/CGLib weaving, which is the default. You can use either runtime weaving with a Java agent or build-time weaving. . . I recommend the former for integration tests and the latter for deployment. . .
Service vs Domain Object:
Now that you have the option of rich domain objects the question becomes where to put stuff. Service vs Entity? My take is that the service should orchestrate a use-case specific process based on reusable domain objects. The service is your non-OO gateway for outside subscribers into you system.
. . Google Spring #Configurable for more information and tutorials on AspectJ-based dependency injection of domain classes.

Dependency injeciton vs global factory

Why do people default to DI vs a global factory with a hashmap that maps interfaces/abstracts to classes? It would seem this is a higher performance solution to the problem no?
All the things mentioned so far in this thread can be provided by a global factory with a method like:
TestGlobalFactory implements GlobalFactoryI
ProductionGlobalFactory implements GlobalFactoryI //configures classes to interfaces
protected GlobalFactoryI gf=GlobalFactoryFactory.getInstance(); //only singleton used in app, specifies which GlobalFactory to use
protected SportsCarI mySportsCar=gf.new("sportsCarI",constructorVar1,constructorVar2);
The above would be much faster than recursive reflection to detect DI instances.
However I admittedly prefer the convention of DI as it ends up being fewer characters and greater flexibility with the option of third party containers.
artima.com/forums/flat.jsp?forum=106&thread=238700
Regardless DI, is the superior approach as it has the containers written to specify which implementation belongs in which class. With Service Locator one would actually have to do gf.new("thisClass","sportsCarI",constructor1)
The main advantage of dependency injection over a factory-based approach is not performance. Its main advantage is testability. The whole point of DI is to be able to inject mock dependencies to implement the unit tests of a component. Doing it with a factory is much more painful.
Because you get a lot more with Spring. Spring manages the lifecycle of its beans, in addition to caching instances in line with the user specified scope for the beans (e.g. prototype, singleton, etc). Also note that Spring's DI is related to its "Inversion of Control", so things are not hard coded directly into the app (unless you consider configuration code).

Setter DI vs. Constructor DI in Spring?

Spring has two two types of DI: setter DI and construction DI.
Constructor-based DI fixes the order in which the dependencies need to be injected. Setter based DI does not offer this.
Setter-based DI helps us to inject the dependency only when it is required, as opposed to requiring it at construction time.
I do not see any other significant differences, as both types of Spring DI provide the same features - both setter and constructor DI inject the dependency when the code starts up. Granted, constructor DI will do it through the constructor while setter DI will do it through a setter right after constructing the object, but it does not make any difference for the developer in terms of performance, etc. Both also offer means to specify the order of dependency injection as well.
I'm looking for a scenario where one provides a distinct advantage over the other or where one type is completely unusable.
When it comes to Spring specific pros and cons:
Constructor injection (from the definition) does not allow you to create circular dependencies between beans. This limitation is actually an advantage of constructor injection - Spring can resolve circular dependencies when setter injection is used without you even noticing.
On the other hand if you use constructor injection CGLIB is not able to create a proxy, forcing you to either use interface-based proxies or a dummy no-arg constructor. See: SPR-3150
You should be deciding based on design considerations, not tool (Spring) considerations. Unfortunately, Spring has trained us to use setter injection because when it was originally conceived, there was no such thing as an "annotation" in Java, and in XML, setter injection works and looks much better. Today, we're freed from those constraints, thus allowing it to be a design decision again. Your beans should use constructor injection for any dependencies that are required by the bean and setter injection for dependencies that are optional and have a reasonable default, more or less as OOD has been telling us from the beginning.
Constructor Injection: We are injecting the dependencies through Constructor.
Generally we can use for Mandatory dependencies.
If you use the Constructor injection there is one disadvantage called "Circular Dependency".
Circular Dependency: Assume A and B. A is dependent on B. B is dependent on A. In this constructor injection will be failed. At that time Setter injection is useful.
If Object state is not inconsistent it won't create Object.
Setter Injection: We are injecting the dependencies through Setter methods.
This is useful for Non-Mandatory dependencies.
It is possible to re injecting dependencies by using Setter Injection. It is not possible in Constructor injection.
As per the content from spring.io from Spring 5 onwards
Since you can mix constructor-based and setter-based DI, it is a good rule of thumb to use constructors for mandatory dependencies and setter methods or configuration methods for optional dependencies. Note that use of the #Required annotation on a setter method can be used to make the property a required dependency.
The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not null. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state. As a side note, a large number of constructor arguments is a bad code smell, implying that the class likely has too many responsibilities and should be refactored to better address proper separation of concerns.
Setter injection should primarily only be used for optional dependencies that can be assigned reasonable default values within the class. Otherwise, not-null checks must be performed everywhere the code uses the dependency. One benefit of setter injection is that setter methods make objects of that class amenable to reconfiguration or re-injection later. Management through JMX MBeans is therefore a compelling use case for setter injection.
Here is the link for above quote
But, all of the injections types are available and none of them are deprecated. At a high-level you get the same functionality across all injection types.
In short, choose the injection type that works best for your team and project.
Recommendations from the Spring team and independent blog posts will vary over time. There is no hard-fast rule.
If a particular injection style was not recommended by the Spring team, then they would mark it as deprecated or obsolete. That is not the case with any of the injection styles.
Prefer setter injection.
Think what would be without spring (as Ryan noted). Would you pass the dependencies in constructor? If there are too many dependencies this seems wrong. On the other hand the constructor may be used to enforce the valid state of the object - require all dependencies and verify if they are non-null.
Proxies are another thing (As Tomasz noted) - you will need a dummy constructor which defeats the whole idea.
There is a 3rd option btw - field injection. I tend to be using that, although it is not such a good design decision, because it saves an extra setter, but if this is used outside of spring I will have to add the setter.
My 2 cents.
Assume a classA with 10 fields, with few injected dependencies.
Now if you need entire classA with all fields then you can go for constructor injection.
But if you need only one of the injected field to use in that class you can use setter injection.
This way,
You will not create new object each time.
You do not need to worry about circular dependency issue(BeanCurrentlyInCreationException).
You will not have to create other fields for class A so you have much more flexible code
Since you can mix both, Constructor DI- and Setter-based DI, it is a good rule of thumb to use constructor arguments for mandatory dependencies and setters for optional dependencies.
Note that the use of a #Required annotation on a setter can be used to make setters required dependencies.
Probably it's not main advantage. But let me explain mechanism of injection in Spring.
The meaning of the difference these two approaches is that with the way of injection using #Inject, #Autowire and so on, Spring will inject one bean into another using reflection, and with the way of the constructor, we ourselves use the constructor in order to initialize one bean by another bean without using reflection.
Therefore, the way with constructor better other option, at least that we don't use reflection-mechanism because reflection is an expensive operation from the machine-side.
P.S. Please consider, that correct use of construction DI it's when you manually create bean through constructor with params, even though you can you create using constructor without any of them.
no, even Constructor Injection happen , injection is still working, but just limited initialize , setter injection is optional and flexible. but it may generally for the parameter class , a spring bean with other spring beans

Resources