Skip to content

Commit dc17bf2

Browse files
committed
Implement new inter-bean-dependencies exercise
1 parent 3321393 commit dc17bf2

File tree

9 files changed

+210
-0
lines changed

9 files changed

+210
-0
lines changed

inter-bean-dependencies/README.MD

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# <img src="https://raw.githubusercontent.com/bobocode-projects/resources/master/image/logo_transparent_background.png" height=50/>Inter-bean dependencies exercise :muscle:
2+
Improve your *Spring ApplicationContext* Java configuration skills
3+
### Task
4+
The task is to **refactor Java configuration class `RootConfig`, in order to properly use Inter-bean dependencies.**
5+
Your job is to follow the instructions in the *todo* section and **implement
6+
a proper configuration.**
7+
8+
To verify your configuration, run `RootConfigContextTest.java` and `RootConfigHacksTest.java`
9+
10+
11+
### Pre-conditions :heavy_exclamation_mark:
12+
You're supposed to be familiar with *Spring IoC* and *Dependency injection* and Proxy pattern
13+
14+
### How to start :question:
15+
* Just clone the repository and start implementing the **todo** section, verify your changes by running tests
16+
* If you don't have enough knowledge about this domain, check out the [links below](#related-materials-information_source)
17+
* Don't worry if you got stuck, checkout the **exercise/completed** branch and see the final implementation
18+
19+
### Related materials :information_source:
20+
* [Injecting Inter-bean Dependencies](https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/core.html#beans-java-injecting-dependencies) <img src="https://spring.io/img/homepage/icon-spring-framework.svg" height=15/>
21+

inter-bean-dependencies/pom.xml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<parent>
6+
<artifactId>spring-framework-exercises</artifactId>
7+
<groupId>com.bobocode</groupId>
8+
<version>1.0-SNAPSHOT</version>
9+
</parent>
10+
<modelVersion>4.0.0</modelVersion>
11+
12+
<artifactId>bean-configuration-exercise</artifactId>
13+
14+
<dependencies>
15+
<dependency>
16+
<groupId>com.bobocode</groupId>
17+
<artifactId>spring-framework-exercises-util</artifactId>
18+
<version>1.0-SNAPSHOT</version>
19+
</dependency>
20+
</dependencies>
21+
</project>
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.bobocode.config;
2+
3+
import com.bobocode.TestDataGenerator;
4+
import com.bobocode.dao.AccountDao;
5+
import com.bobocode.dao.impl.FakeAccountDao;
6+
import com.bobocode.service.AccountService;
7+
import org.springframework.context.annotation.Bean;
8+
import org.springframework.stereotype.Component;
9+
10+
/**
11+
* todo: Refactor {@link RootConfig} in order to user inter-bean dependencies properly.
12+
*/
13+
@Component
14+
public final class RootConfig {
15+
16+
@Bean
17+
public AccountService accountService() {
18+
return new AccountService(fakeAccountDao());
19+
}
20+
21+
@Bean
22+
public final AccountDao fakeAccountDao() {
23+
return new FakeAccountDao(dataGenerator());
24+
}
25+
26+
@Bean
27+
private TestDataGenerator dataGenerator() {
28+
return new TestDataGenerator();
29+
}
30+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.bobocode.dao;
2+
3+
import com.bobocode.model.Account;
4+
5+
public interface AccountDao {
6+
Account findById(Long id);
7+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.bobocode.dao.impl;
2+
3+
import com.bobocode.TestDataGenerator;
4+
import com.bobocode.dao.AccountDao;
5+
import com.bobocode.model.Account;
6+
import lombok.Getter;
7+
import lombok.RequiredArgsConstructor;
8+
9+
@Getter
10+
@RequiredArgsConstructor
11+
public class FakeAccountDao implements AccountDao {
12+
private final TestDataGenerator dataGenerator;
13+
14+
@Override
15+
public Account findById(Long id) {
16+
Account account = dataGenerator.generateAccount();
17+
account.setId(id);
18+
return account;
19+
}
20+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.bobocode.service;
2+
3+
import com.bobocode.dao.AccountDao;
4+
import lombok.Getter;
5+
import lombok.RequiredArgsConstructor;
6+
7+
@Getter
8+
@RequiredArgsConstructor
9+
public class AccountService {
10+
private final AccountDao accountDao;
11+
12+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.bobocode;
2+
3+
import com.bobocode.config.RootConfig;
4+
import com.bobocode.dao.impl.FakeAccountDao;
5+
import com.bobocode.service.AccountService;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.beans.factory.annotation.Autowired;
8+
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
9+
10+
import static org.assertj.core.api.Assertions.assertThat;
11+
12+
13+
@SpringJUnitConfig(classes = RootConfig.class)
14+
class RootConfigContextTest {
15+
16+
@Autowired
17+
private AccountService accountService;
18+
19+
@Autowired
20+
private FakeAccountDao accountDao;
21+
22+
@Autowired
23+
private TestDataGenerator dataGenerator;
24+
25+
@Test
26+
void dataGeneratorShouldHaveScopeSingleton() {
27+
assertThat(accountDao.getDataGenerator()).isEqualTo(dataGenerator);
28+
}
29+
30+
@Test
31+
void accountDaoShouldHaveScopeSingleton() {
32+
assertThat(accountService.getAccountDao()).isEqualTo(accountDao);
33+
}
34+
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.bobocode;
2+
3+
import com.bobocode.config.RootConfig;
4+
import com.bobocode.dao.impl.FakeAccountDao;
5+
import com.bobocode.service.AccountService;
6+
import org.junit.jupiter.api.Test;
7+
import org.springframework.context.annotation.ComponentScan;
8+
import org.springframework.context.annotation.Import;
9+
import org.springframework.stereotype.Component;
10+
import org.springframework.stereotype.Service;
11+
12+
import java.lang.annotation.Annotation;
13+
import java.lang.reflect.Method;
14+
import java.util.List;
15+
import java.util.stream.Collectors;
16+
import java.util.stream.Stream;
17+
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
20+
class RootConfigHacksTest {
21+
22+
@Test
23+
void rootConfigShouldNotUseComponentScan() {
24+
ComponentScan componentScan = RootConfig.class.getAnnotation(ComponentScan.class);
25+
26+
assertThat(componentScan).isNull();
27+
}
28+
29+
@Test
30+
void rootConfigShouldNotImportOtherConfigs() {
31+
Import importAnnotation = RootConfig.class.getAnnotation(Import.class);
32+
33+
assertThat(importAnnotation).isNull();
34+
}
35+
36+
@Test
37+
void accountServiceBeanShouldBeConfiguredExplicitly() {
38+
Annotation[] annotations = AccountService.class.getAnnotations();
39+
List<Class> annotationClasses = Stream.of(annotations).map(Annotation::annotationType).collect(Collectors.toList());
40+
41+
assertThat(annotationClasses).doesNotContain(Component.class, Service.class);
42+
}
43+
44+
@Test
45+
void fakeAccountDaoBeanShouldBeConfiguredExplicitly() {
46+
Annotation[] annotations = FakeAccountDao.class.getAnnotations();
47+
List<Class> annotationClasses = Stream.of(annotations).map(Annotation::annotationType).collect(Collectors.toList());
48+
49+
assertThat(annotationClasses).doesNotContain(Component.class, Service.class);
50+
}
51+
52+
@Test
53+
void rootConfigShouldUseInterBeanDependencies() {
54+
Method[] methods = RootConfig.class.getDeclaredMethods();
55+
56+
assertThat(methods).noneMatch(method -> method.getParameterCount() > 0);
57+
}
58+
}

pom.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
<module>account-jsp</module>
1616
<module>account-rest-api</module>
1717
<module>transactional-user-service</module>
18+
<module>inter-bean-dependencies</module>
1819
</modules>
1920
<packaging>pom</packaging>
2021

@@ -78,6 +79,12 @@
7879
<artifactId>slf4j-simple</artifactId>
7980
<version>1.7.24</version>
8081
</dependency>
82+
<dependency>
83+
<groupId>org.assertj</groupId>
84+
<artifactId>assertj-core</artifactId>
85+
<version>3.13.2</version>
86+
<scope>test</scope>
87+
</dependency>
8188
</dependencies>
8289

8390
<build>

0 commit comments

Comments
 (0)