[JAVA-8290] Split spring-di module

This commit is contained in:
Haroon Khan
2021-12-22 21:24:24 +00:00
parent 1356116683
commit c5fcbb18d5
28 changed files with 159 additions and 77 deletions

View File

@@ -5,13 +5,10 @@ This module contains articles about dependency injection with Spring
### Relevant Articles
- [The Spring @Qualifier Annotation](https://www.baeldung.com/spring-qualifier-annotation)
- [Constructor Dependency Injection in Spring](https://www.baeldung.com/constructor-injection-in-spring)
- [Spring Autowiring of Generic Types](https://www.baeldung.com/spring-autowire-generics)
- [Guice vs Spring Dependency Injection](https://www.baeldung.com/guice-spring-dependency-injection)
- [Injecting Prototype Beans into a Singleton Instance in Spring](https://www.baeldung.com/spring-inject-prototype-bean-into-singleton)
- [@Lookup Annotation in Spring](https://www.baeldung.com/spring-lookup)
- [Controlling Bean Creation Order with @DependsOn Annotation](https://www.baeldung.com/spring-depends-on)
- [Unsatisfied Dependency in Spring](https://www.baeldung.com/spring-unsatisfied-dependency)
- [Circular Dependencies in Spring](https://www.baeldung.com/circular-dependencies-in-spring)
- [XML-Based Injection in Spring](https://www.baeldung.com/spring-xml-injection)
- More articles: [[next -->]](/spring-di-2)
- More articles: [[next -->]](../spring-di-2)

View File

@@ -1,29 +0,0 @@
package com.baeldung.circulardependency;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class CircularDependencyA implements ApplicationContextAware, InitializingBean {
private CircularDependencyB circB;
private ApplicationContext context;
public CircularDependencyB getCircB() {
return circB;
}
@Override
public void afterPropertiesSet() throws Exception {
circB = context.getBean(CircularDependencyB.class);
}
@Override
public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
context = ctx;
}
}

View File

@@ -1,22 +0,0 @@
package com.baeldung.circulardependency;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class CircularDependencyB {
private CircularDependencyA circA;
private String message = "Hi!";
@Autowired
public void setCircA(final CircularDependencyA circA) {
this.circA = circA;
}
public String getMessage() {
return message;
}
}

View File

@@ -1,23 +0,0 @@
package com.baeldung.constructordi;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import com.baeldung.constructordi.domain.Engine;
import com.baeldung.constructordi.domain.Transmission;
@Configuration
@ComponentScan("com.baeldung.constructordi")
public class Config {
@Bean
public Engine engine() {
return new Engine("v8", 5);
}
@Bean
public Transmission transmission() {
return new Transmission("sliding");
}
}

View File

@@ -1,31 +0,0 @@
package com.baeldung.constructordi;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.baeldung.constructordi.domain.Car;
public class SpringRunner {
public static void main(String[] args) {
Car toyota = getCarFromXml();
System.out.println(toyota);
toyota = getCarFromJavaConfig();
System.out.println(toyota);
}
private static Car getCarFromJavaConfig() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
return context.getBean(Car.class);
}
private static Car getCarFromXml() {
ApplicationContext context = new ClassPathXmlApplicationContext("constructordi.xml");
return context.getBean(Car.class);
}
}

View File

@@ -1,21 +0,0 @@
package com.baeldung.constructordi.domain;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class Car {
private Engine engine;
private Transmission transmission;
@Autowired
public Car(Engine engine, Transmission transmission) {
this.engine = engine;
this.transmission = transmission;
}
@Override
public String toString() {
return String.format("Engine: %s Transmission: %s", engine, transmission);
}
}

View File

@@ -1,16 +0,0 @@
package com.baeldung.constructordi.domain;
public class Engine {
private String type;
private int volume;
public Engine(String type, int volume) {
this.type = type;
this.volume = volume;
}
@Override
public String toString() {
return String.format("%s %d", type, volume);
}
}

View File

@@ -1,14 +0,0 @@
package com.baeldung.constructordi.domain;
public class Transmission {
private String type;
public Transmission(String type) {
this.type = type;
}
@Override
public String toString() {
return String.format("%s", type);
}
}

View File

@@ -1,10 +0,0 @@
package com.baeldung.methodinjections;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = "com.baeldung.methodinjections")
public class AppConfig {
}

View File

@@ -1,19 +0,0 @@
package com.baeldung.methodinjections;
import java.util.Collection;
import org.springframework.stereotype.Component;
@Component
public class Grader {
public String grade(Collection<Integer> marks) {
boolean result = marks.stream()
.anyMatch(mark -> mark < 45);
if (result) {
return "FAIL";
}
return "PASS";
}
}

View File

@@ -1,45 +0,0 @@
package com.baeldung.methodinjections;
import java.util.ArrayList;
import java.util.Collection;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component("schoolNotification")
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class SchoolNotification {
@Autowired
Grader grader;
private String name;
private Collection<Integer> marks;
public SchoolNotification(String name) {
this.name = name;
this.marks = new ArrayList<Integer>();
}
public String addMark(Integer mark) {
this.marks.add(mark);
return this.grader.grade(this.marks);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<Integer> getMarks() {
return marks;
}
public void setMarks(Collection<Integer> marks) {
this.marks = marks;
}
}

View File

@@ -1,27 +0,0 @@
package com.baeldung.methodinjections;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component("studentBean")
public class Student {
private String id;
/**
* Injects a prototype bean SchoolNotification into Singleton student
*/
@Lookup
public SchoolNotification getNotification(String name) {
// spring overrides and returns a SchoolNotification instance
return null;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}

View File

@@ -1,21 +0,0 @@
package com.baeldung.methodinjections;
import java.util.HashMap;
import java.util.Map;
import org.springframework.beans.factory.annotation.Lookup;
import org.springframework.stereotype.Component;
@Component("studentService")
public abstract class StudentServices {
private Map<String, SchoolNotification> notes = new HashMap<>();
@Lookup
protected abstract SchoolNotification getNotification(String name);
public String appendMark(String name, Integer mark) {
SchoolNotification notification = notes.computeIfAbsent(name, exists -> getNotification(name));
return notification.addMark(mark);
}
}

View File

@@ -1,15 +0,0 @@
<?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.baeldung.methodinjections" />
<bean id="schoolNotification" class="com.baeldung.methodinjections.SchoolNotification" scope="prototype"/>
<bean id="studentServices" class="com.baeldung.methodinjections.StudentServices" scope="prototype" >
<lookup-method name="getNotification" bean="schoolNotification"/>
</bean>
</beans>

View File

@@ -1,22 +0,0 @@
<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
https://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="toyota" class="com.baeldung.constructordi.domain.Car">
<constructor-arg index="0" ref="engine" />
<constructor-arg index="1" ref="transmission" />
</bean>
<bean id="engine"
class="com.baeldung.constructordi.domain.Engine">
<constructor-arg index="0" value="v4" />
<constructor-arg index="1" value="2" />
</bean>
<bean id="transmission"
class="com.baeldung.constructordi.domain.Transmission">
<constructor-arg value="sliding" />
</bean>
</beans>

View File

@@ -1,35 +0,0 @@
package com.baeldung.circulardependency;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
public class CircularDependencyIntegrationTest {
@Autowired
ApplicationContext context;
@Bean
public CircularDependencyA getCircularDependencyA() {
return new CircularDependencyA();
}
@Bean
public CircularDependencyB getCircularDependencyB() {
return new CircularDependencyB();
}
@Test
public void givenCircularDependency_whenSetterInjection_thenItWorks() {
final CircularDependencyA circA = context.getBean(CircularDependencyA.class);
Assert.assertEquals("Hi!", circA.getCircB().getMessage());
}
}

View File

@@ -1,10 +0,0 @@
package com.baeldung.circulardependency;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = { "com.baeldung.circulardependency" })
public class TestConfig {
}

View File

@@ -1,33 +0,0 @@
package com.baeldung.constructordi;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.AnnotationConfigContextLoader;
import com.baeldung.constructordi.domain.Car;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class, classes = Config.class)
public class ConstructorDependencyInjectionIntegrationTest {
@Test
public void givenPrototypeInjection_WhenObjectFactory_ThenNewInstanceReturn() {
ApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
Car firstContextCar = context.getBean(Car.class);
ApplicationContext xmlContext = new ClassPathXmlApplicationContext("constructordi.xml");
Car secondContextCar = xmlContext.getBean(Car.class);
assertThat(firstContextCar).isNotSameAs(secondContextCar);
assertThat(firstContextCar).hasToString("Engine: v8 5 Transmission: sliding");
assertThat(secondContextCar).hasToString("Engine: v4 2 Transmission: sliding");
}
}

View File

@@ -1,31 +0,0 @@
package com.baeldung.methodinjections;
import org.junit.Assert;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class StudentIntegrationTest {
@Test
public void whenLookupMethodCalled_thenNewInstanceReturned() {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
Student student1 = context.getBean("studentBean", Student.class);
Student student2 = context.getBean("studentBean", Student.class);
Assert.assertEquals(student1, student2);
Assert.assertNotEquals(student1.getNotification("Alex"), student2.getNotification("Bethany"));
context.close();
}
@Test
public void whenAbstractGetterMethodInjects_thenNewInstanceReturned() {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
StudentServices services = context.getBean("studentServices", StudentServices.class);
Assert.assertEquals("PASS", services.appendMark("Alex", 76));
Assert.assertEquals("FAIL", services.appendMark("Bethany", 44));
Assert.assertEquals("PASS", services.appendMark("Claire", 96));
context.close();
}
}