Reference https://medium.com/@ilyailin7777/all-dependency-injection-types-spring-336da7baf51b
Types of Dependency Injection:
- Constructor.
- Setter.
- Field.
- lookup method.
1.- Constructor Injection (Immutable)
package com.bext
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
class ServiceA { void method() { System.out.println("ServiceA");
} } class ServiceB { void method() { System.out.println("ServiceB");
} } class DependentService { private final ServiceA serviceA;
private final ServiceB serviceB; public DependentService(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA;
this.serviceB = serviceB;
} void method() { service1.method();
service2.method();
} } public class Main { public static void main(String[] args) { ApplicationContext container = new ClassPathXmlApplicationContext("spring.xml");
((DependentService) container.getBean("dependentService")).method(); } }
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="serviceA" class="com.bext.ServiceA"/>
<bean id="serviceB" class="com.bext.ServiceB"/>
<bean id="dependentService" class="com.bext.DependentService">
<constructor-arg type="com.bext.ServiceA" ref="serviceA"/>
<constructor-arg type="com.bext.ServiceB" ref="serviceB"/>
</bean> </beans>
Using Annotations
package com.bext; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Service;
@Service class ServiceA { void method() { System.out.println("ServiceA");
} } @Service class ServiceB { void method() { System.out.println("ServiceB");
} } @Service class DependentService { private final ServiceA serviceA;
private final ServiceB serviceB;
@Autowired public DependentService(ServiceA serviceA, ServiceB serviceB) { this.serviceA = serviceA;
this.serviceB = serviceB;
} void method() { serviceA.method();
serviceB.method();
} } public class Main { public static void main(String[] args) { ApplicationContext container = new ClassPathXmlApplicationContext("spring.xml");
((DependentService) container.getBean("dependentService")).method();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.bext"/>
</beans>
Advantages
- Constructed objects are immutable and returned initialized.
- More dependencies bigger the constructor.
- can be combined with setter injection of field injector, constructor parameters indicate
required dependencies.
Disadvantages
- No possiblitiy to change object's dependencies later.
- Higher change to have circular dependencies.
2.- Setter Injection ( mutability )
class DependentService { private ServiceA serviceA;
private ServiceB serviceB;
public void setServiceA(ServiceA serviceA) { this.serviceA = serviceA;
} public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB;
} void method() { serviceA.method(); serviceB.method();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="serviceA" class="com.bext.ServiceA"/>
<bean id="serviceB" class="com.bext.ServiceB"/>
<bean id="dependentService" class="com.bext.DependentService">
<property name="serviceA" ref="serviceA"/>
<property name="serviceB" ref="serviceB"/>
</bean> </beans>
Using Annotations
@Service class DependentService { private ServiceA serviceA;
private ServiceB serviceB;
@Autowired public void setServiceA(ServiceA serviceA) { this.serviceA = serviceA;
} @Autowired public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB;
} void method() { serviceA.method();
serviceB.method();
}
}
with mandatory dependency (ServiceA final property)
@Service class DependentService { private final ServiceA serviceA;
private ServiceB serviceB;
@Autowired public void DependentService(ServiceA serviceA) { this.serviceA = serviceA;
} @Autowired public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB;
} void method() { serviceA.method();
serviceB.method();
}
}
Advantages
- Flexibility in dependency resolution or object reconfiguration, at any time.
Disadvantages
- Null checks are required.
- Potentially more error prone and less secure than constructor injection. (by overriding dependencies).
3.- Field Injection
@Service class DependentService { @Autowired private ServiceA serviceA;
@Autowired
private ServiceB serviceB;
void method() {
serviceA.method(); serviceB.method(); }
}
Spring Uses reflection to set these values
Advantages
- Easy to use, no constructors or setters required.
- Can be easily combined with the constructor and/or setter approach.
Disadvantages
- Less control over object instantiation.
- A number of dependencies can reach dozens until realize that something went wrong.
- mutability.
4.- Lookup Method Injection
Each time method is called, a new ServiceA is created, so the scope is prototype. the default is singleton.
abstract class DependentService { private ServiceB serviceB;
public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB;
} void method() { createServiceA().method();
serviceB.method();
} protected abstract ServiceA createService1();
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="serviceA" class="com.bext.ServiceA" scope="prototype"/>
<bean id="serviceB" class="com.bext.ServiceB"/> <bean id="dependentService" class="com.bext.DependentService">
<lookup-method name="createServiceA" bean="serviceA"/>
<property name="serviceB" ref="serviceB"/>
</bean> </beans>
Using Annotations
@Service @Scope(value = "prototype") class ServiceA { void method() { System.out.println("ServiceA");
} } @Service abstract class DependentService { private ServiceB serviceB;
@Autowired public void setServiceB(ServiceB serviceB) { this.serviceB = serviceB;
} void method() { createServiceA().method();
serviceB.method();
} @Lookup protected abstract ServiceA createServiceA();
}
No hay comentarios:
Publicar un comentario