Stack을 쓰는 이유
import java.util.Arrays;
public class Stack01 {
private int[] arr = new int[10000];
private int pointer = 0;
public Stack01() {
}
public Stack01(int size) {
this.arr = new int[size];
}
public void push(int value) {
this.arr[this.pointer] = value;
this.pointer++;
}
public int pop() {
this.pointer--;
return this.arr[this.pointer];
}
public int[] getArr() {
return arr;
}
public static void main(String[] args) {
Stack01 stack01 = new Stack01();
stack01.push(10);
stack01.push(20);
System.out.println(Arrays.toString(stack01.getArr()));
System.out.println(stack01.pop());
System.out.println(Arrays.toString(stack01.getArr()));
}
}
ConnectionMaker
import java.sql.Connection;
import java.sql.SQLException;
public interface ConnectionMaker {
public Connection getConnection() throws ClassNotFoundException, SQLException;
}
AwsConnectionMaker
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Map;
public class AwsConnectionMaker implements ConnectionMaker{
public Connection getConnection() throws ClassNotFoundException, SQLException {
Map<String, String> env = System.getenv();
String dbHost = env.get("DB_HOST");
String dbName = env.get("DB_NAME");
String dbPassword = env.get("DB_PASSWORD");
Class.forName("com.mysql.cj.jdbc.Driver");
Connection conn = DriverManager.getConnection(dbHost, dbName, dbPassword);
return conn;
}
}
UserDao 일부 코드
public class UserDao {
private ConnectionMaker connectionMaker;
// 매개 변수가 없다면 새로 생성하고
// 받은 매개 변수가 있다면 awsConnectionMaker에 할당
public UserDao() {
this.connectionMaker = new AwsConnectionMaker();
}
public UserDao(ConnectionMaker connectionMaker) {
this.connectionMaker = connectionMaker;
}
public void add(User user) throws SQLException, ClassNotFoundException {
Connection conn = connectionMaker.getConnection();
PreparedStatement ps = conn.prepareStatement("INSERT INTO users(id, name, password) VALUES (?, ?, ?)");
ps.setString(1, user.getId());
ps.setString(2, user.getName());
ps.setString(3, user.getPassword());
ps.executeUpdate();
ps.close();
conn.close();
}
🔴 이해 과정
1. getConnection()를 갖고 있는 ConnectionMaker 인터페이스 생성
2. ConnectionMaker를 implements하는 AwsConnectionMaker 생성
3. AwsConnectionMaker에서 ConnectionMaker의 getConnection() 완성
4. UserDao에서 ConnectionMaker connectionMaker 선언
this.connectionMaker = new AwsConnectionMaker(); : AwsConnectionMaker은 ConnectionMaker를 implements하기 때문에 초기화 가능조립 설정 (어떤 조합을 사용할 것인지)
public class UserDaoFactory {
// Factory는 조립을 해줌 - DAO에서는
public UserDao awsUserDao() {
AwsConnectionMaker awsConnectionMaker = new AwsConnectionMaker();
// context 재사용 하는 부분이 많은 코드
UserDao userDao = new UserDao(awsConnectionMaker);
return userDao;
}
}
🟢 이해 과정
1. UserDaoFactory 클래스 생성
2. AwsConnectionMaker 객체를 만들어서 UserDao에 넣어 조립해 준 후 리턴
3. 코드 변화
🟢 기존 코드
UserDao userDao = new UserDao(new AwsConnectionMaker());
🟢 Factory 적용후
UserDao userDao = new UserDaoFactory().awsUserDao();
Spring 사용 이유
1. Bean을 만들어 놓고 불러 쓰기가 좋기 때문에 씀
2. Singleton으로 생성을 해주기 때문에 씀(🔴 객체의 인스턴스가 오직 1개만 생성되는 패턴)
- getBean을 사용하면 같은 주소(객체 하나)
- factory.userDao()로 각각 객체를 생성하면 (객체 2개)
👉 즉, Singleton을 사용하는 것은 GC(Garbage Collection)을 줄일 수 있음
Spring 적용 방법
Factory에 Spring 적용
🟢 UserDaoFactory
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class UserDaoFactory {
// Factory는 조립을 해줌 - DAO에서는
@Bean
public UserDao awsUserDao() {
AwsConnectionMaker awsConnectionMaker = new AwsConnectionMaker();
// context 재사용 하는 부분이 많은 코드
UserDao userDao = new UserDao(awsConnectionMaker);
return userDao;
}
@Bean
public UserDao localUserDao() {
UserDao userDao = new UserDao(new LocalConnectionMaker());
return userDao;
}
}
🟢 UserDaoTest
import likelion.domain.User;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import java.sql.SQLException;
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = UserDaoFactory.class)
class UserDaoTest {
@Autowired
ApplicationContext context;
@Test
void addAndSelect() throws SQLException, ClassNotFoundException {
UserDao userDao = context.getBean("awsUserDao", UserDao.class);
User user = new User("10", "Lotto", "6666");
// userDao.add(user);
User selectedUser = userDao.findbyId("10");
Assertions.assertEquals("Lotto", selectedUser.getName());
}
}