[Spring] Design Game Runner with Spring Boot
Starting Spring Framework(1)
/Interface / @Bean / getBean / 클래스 record
- Design Game Runner to run games(Mario, SuperContra, Pacman etc) in an iterative approach:
- Iteration 1: Tightly Copuled Java Code
- GameRunner class
- Game classes: Mario, SuperContra, Pacman etc
- Iteration 2: Loose Coupling - interfaces
- GameRunner class
- GamingConsole interface
- Game classes: Mario, SuperContra, Pacman etc
- Iteration 1: Tightly Copuled Java Code
Why is Coupling Important?
- Coupling: How much work is involved in changing something?
- Coupling is important everywhere:
- An engine is tightly coupled to a Car
- A Wheel is loosely coupled to a Car
- You can take a laptop anywhere you go
- A computer, on the other hand, is a little bit more difficult to move
- Coupling is even more important in building great software
- only thing constant in technology is change
- Business requirements change
- Frameworks change
- Code changes
- We want Loose Coupling as much as possible
- We want to make functional changes with as less code changes code as possible
- only thing constant in technology is change
- Coupling is important everywhere:
Tightly Copuled Java Code
-
- 의존성이 매우 높음
- 마리오 게임에서 슈퍼콘트라로 바꾸려면 관련된 것들을 다 바꿔줘야함
- 의존성이 매우 높음
Loose Coupling - interfaces
-
- 이렇게 인터페이스를 만들면 동일 메소드에서 갈아끼워서 사용가능하다.
- 막상 답답함을 느껴보니 왜 인터페이스를 사용하는지 알거 같다
- 하지만 여기서 Spring을 추가한다면?!
Spring! Bean으로 관리하기
Practice!
public class App02HelloWorldSpring {
public static void main(String[] args) {
//1: Launch a Spring Context
var context =
new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
//2: Configure the things that we want Spring to manage - @Configuration
//HelloWorldConfiguration - @Configuration //name -@Bean
//3: Retrieving Beans managed by Spring System.out.println(context.getBean("name"));
System.out.println(context.getBean("age"));
System.out.println(context.getBean("person"));
System.out.println(context.getBean("address"));
}
}
package com.in28minutes.learinspringframework;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
//Eliminate verbosity in creating Java Beans
//Public accessor methods, constructor
//equals, hashcode and toString are automatically created
//Released in JDK 16 (record)
record Person (String name, int age){};
//Address
record Address(String firstLine, String city){};
@Configuration
public class HelloWorldConfiguration {
@Bean
public String name() {
return "Yoyo";
}
@Bean
public int age() {
return 18;
}
@Bean
public Person person(){
return new Person("J", 20);
}
@Bean
public Address address(){
return new Address("Bupyeong", "Incheon");
}
}
- Java 16 이후
record
덕분에 getter setter 등 이전보다 훨씬 편하게 작성 가능- 생성자 작성 필요 X
- toString, equals, hashCode 등 자동으로 생성됨
참고 : https://scshim.tistory.com/372
@Bean -> name 재정의
@Bean(name = "address2")
public Address address(){
return new Address("Bupyeong", "Incheon");
}
public class App02HelloWorldSpring {
public static void main(String[] args) {
...
var context =
new AnnotationConfigApplicationContext(HelloWorldConfiguration.class);
...
System.out.println(context.getBean("address2"));
}
}
How you retrieve the beans back from spring context
System.out.println(context.getBean(Address.class));
- Once spring Starts managing a bean, you can either use the name of the bean or you can use the type of the bean to be able to get it back and play with it
이미 존재하는 Bean 으로 새로운 Bean 만들기
@Bean
public String name() {
return "Yoyo";
}
@Bean
public int age() {
return 18;
}
@Bean
public Person person2MethodCall(){
return new Person(name(), age());
}
새로운 Bean 추가
//Released in JDK 16 (record)
record Person (String name, int age, Address address){};
//Address
record Address(String firstLine, String city){};
@Configuration
public class HelloWorldConfiguration {
@Bean
public String name() {
return "Yoyo";
}
@Bean
public int age() {
return 18;
}
@Bean
public Person person(){
return new Person("J", 20, new Address("Marine","Port"));
}
@Bean
public Person person2MethodCall(){
return new Person(name(), age(), address());
}
@Bean(name = "address2")
public Address address(){
return new Address("Bupyeong", "Incheon");
}
}
출력
Alternative approach
//Released in JDK 16 (record)
record Person (String name, int age, Address address){};
//Address
record Address(String firstLine, String city){};
@Configuration
public class HelloWorldConfiguration {
.....
@Bean
public Person person3Parameters(String name, int age, Address address2){
return new Person(name, age, address2);
}
}
- 메소드를 직접 부르는거 대신에 파라미터로 부를 수 있다.
- (name, age, address2);
정리
- The first thing we learnt is the fact that you can configure your own custom names for your beans.
- So instead of just using the default method Dimm, you can configure your own custom name.
- The second thing we learned was the fact that you can retrieve the beans from a spring context in multiple ways.
- One of the ways is by using a bean name.
- The other one is to use the type of the class name as well.
- The third thing that we learned is that you can use existing beans, which are managed by spring to create new beans.
- So we are now creating a person three in here using existing beans, which are managed by spring framework.
Spring 으로 관리
Basic (Before)
public class App01GamingBasicJava {
public static void main(String[] args) {
//var marioGame = new MarioGame();
var superContraGame = new SuperContraGame(); // 1: Object creation
var gameRunner = new GameRunner(superContraGame);
// 2: Object Creation + Wiring of Dependencies
// Game is a Dependency of GameRunner
gameRunner.run();
}
}
- 인터페이스를 만들어서 갈아 끼우는 방식으로 관리
Spring (New)
public class App03GamingSpringBeans {
public static void main(String[] args) {
var context =
new AnnotationConfigApplicationContext(GamingConfiguration.class);
context.getBean(GamingConsole.class).up();
context.getBean(GameRunner.class).run();
}
}
@Configuration
public class GamingConfiguration {
@Bean
public GamingConsole game() {
var game = new PacmanGame();
return game;
}
@Bean
public GameRunner gameRunner(GamingConsole game) {
var gameRunner = new GameRunner(game);
return gameRunner;
}
}
- Spring 으로 관리하게 만드는게 더 적은 코드를 쓰는 것도 아니고 interface 등 그대로 유지된 상태에서 더 얹는 느낌이다.
- 그럼 Spring이 어느 부분에서 도대체 왜!! 좋은걸까?
- Starting Spring Framework(5) 에 정리
댓글남기기