스프링은 자바를 기반으로 한 기술이자, 자바 엔터프라이즈 어플리케이션 개발에 사용되는 프레임워크이다. 어플리케이션 프레임워크는 어플리케이션 개발을 빠르고 효율적으로 할 수 있도록 어플리케이션의 바탕이 되는 틀과 공통 프로그래밍 모델, API 등을 지원해준다.
스프링이 자바에서 가장 중요하게 가치 두는 것은 객체지향 프로그래밍이 가능한 언어라는 점이다. 특히, 그 중에서도 오브젝트에 가장 많이 관심을 둔다.
어플리케이션에서 오브젝트가 생성되고, 다른 오브젝트와 관계를 가지는지 등은 스프링에서의 객체 지향에서 가장 중점적인 내용이다.
스프링은 다음 세 가지 핵심 프로그래밍 모델을 지원한다.
- IOC/ DI : 오브젝트의 생명 주기와 의존관계에 대한 프로그래밍 모델
- 서비스 추상화 : 환경이나 서버, 특정 기술에 종속되지 않고 이식성이 뛰어나고 flexible한 어플리케이션을 만들 수 있다.
- AOP : 어플리케이션 코드에 산재해서 나타나는 부가적인 기능을 독립저긍로 모듈화하는 프로그래밍 모델
DAO 설계와 분리, 확장
- 디폴트 생성자 : 자바빈은 파라미터가 없는 디폴트 생성자를 갖고 있어야 한다.
- 프로퍼티 : 자바빈이 노출하는 이름을 가진 속성을 프로퍼티라고 한다. 프로퍼티는 setter 와 getter 를 이용해 수정 또는 조회할 수 있다.
디자인 패턴
public abstract class UserDao {
public void add(User user) throws ClassNotFoundException, SQLException {
Connection c = getConnection(); // Connection 인터페이스에 정의된 메소드 사용
PreparedStatement ps = c.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();
c.close();
}
public User get(String id) throws ClassNotFoundException, SQLException {
Connection c = getConnection(); // Connection 인터페이스에 정의된 메소드 사용
PreparedStatement ps = c.prepareStatement("select * from users where id=?");
ps.setString(1, id);
ResultSet rs = ps.executeQuery();
rs.next();
User user = new User();
user.setId(rs.getString("id"));
user.setName(rs.getString("name"));
user.setPassword(rs.getString("password"));
rs.close();
ps.close();
c.close();
return user;
}
public abstract Connection getConnection() throws ClassNotFoundException, SQLException;
}
public class NUserDao extends UserDao {
public Connection getConnection() throws ClassNotFoundException, SQLException {
// N사 DB Connection 생성 코드
}
}
public class DUserDao extends UserDao {
public Connection getConnection() throws ClassNotFoundException, SQLException {
// D사 DB Connection 생성 코드
}
}
Class.forName("com.mysql.jdbc.Driver");
Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?useSSL=false", "spring", "book");
return c;
클래스 사이의 관계 vs 오브젝트 사이의 관계
개방 폐쇄 원칙(OCP)
전략 패턴
제어의 역전(IoC)
User.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | package springbooks.user.domain; public class User { String id; String name; String password; public void setId(String id){ this.id = id; } public String getId() { return id; } public void setName(String name){ this.name = name; } public String getName() { return name; } public void setPassword(String password){ this.password = password; } public String getPassword() { return password; } } | cs |
UserDao.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 | package springbooks.user.userdao; import springbooks.user.domain.User; import java.sql.*; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; public class UserDao { private ConnectionMaker connectionMaker; //밑에서 DI 받고 있으므로 특정클래스 타입이면 안됨. 인터페이스 타입. //의존관계 주입을 위한 코드 : 런타임 의존관계를 갖는 오브젝트를 인스턴스 변수에 저장해주기 public UserDao(ConnectionMaker connectionMaker) { //오브젝트를 한 번만 만들어주기 위해 생성자에 넣어준 것. this.connectionMaker = connectionMaker; //생성자를 통해 DConnectionMaker 오브젝트 간접 전달 (직접 전달하면 코드 수정이 불가피) } public void add(User user) throws ClassNotFoundException, SQLException{ Connection c = connectionMaker.makeConnection(); PreparedStatement ps = c.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(); c.close(); } public User get(String id) throws ClassNotFoundException, SQLException{ Connection c = connectionMaker.makeConnection(); PreparedStatement ps = c.prepareStatement("select * from users where id=?"); ps.setString(1, id); ResultSet rs = ps.executeQuery(); rs.next(); User user = new User(); user.setId(rs.getString("id")); user.setName(rs.getString("name")); user.setPassword(rs.getString("password")); rs.close(); ps.close(); c.close(); return user; } } //db연결방식을 정의할 수 있는 틀 : interface interface ConnectionMaker { public Connection makeConnection() throws ClassNotFoundException, SQLException; } //고객이 구현할 자신들의 DB연결 코드 -> 전략을 바꿔가면서 사용할 수 있게끔 class DConnectionMaker implements ConnectionMaker { public Connection makeConnection() throws ClassNotFoundException, SQLException{ Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://localhost/springbook?useSSL=false", "spring", "book"); return c; } } //내가 만든 ConnectionMaker 구현 클래스를 어떤 것을 사용할 지를 결정한 권한을 가진 클래스 //UserDao는 이제 수동적인 존재가 됐음 -> ConnectionMaker를 사용하지만 제어하는 기능이 없음 : 제어의 역전 class DaoFactory { public UserDao userDao() { //UserDao가 사용할 오브젝트를 DaoFactory에서 공급해주고 있음 return new UserDao(connectionMaker()); //파라미터로 오브젝트의 레퍼런스 전달 } //DI컨테이너 자신이 결정한 의존관계를 맺어줄 클래스의 오브젝트를 만드는 코드 public ConnectionMaker connectionMaker() { return new DConnectionMaker(); } } | cs |
MainTest.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package springbooks.user.userdao; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import springbooks.user.domain.User; import java.sql.*; //ConnectionMaker와 UserDao을 연결시켜주는 제 3의 클라이언트 클래스 public class MainTest { public static void main(String[] args) throws ClassNotFoundException, SQLException { UserDao dao = new DaoFactory().userDao(); User user = new User(); user.setId("whiteship"); user.setName("백기선"); user.setPassword("married"); dao.add(user); System.out.println(user.getId() + " 등록 성공"); User user2 = dao.get(user.getId()); System.out.println(user2.getName()); System.out.println(user.getPassword()); System.out.println(user2.getId() + " 조회 성공"); } } | cs |
제어의 역전
'Programming > Spring' 카테고리의 다른 글
[Selenium + Headless Chromium] Java로 인스타그램 대용량 크롤링하기 2 - 배치 프로그램 (1) | 2019.10.04 |
---|---|
[Selenium + Headless Chromium] Java로 인스타그램 대용량 크롤링하기 1 (361) | 2019.10.02 |
[Spring-batch] ItemWriter 클래스 구현기 (오류 해결) (2) | 2019.09.08 |
[Spring-boot] Facebook Timeline 프로젝트 : MySQL, JPA 개발 환경 구성하기 (3) | 2019.07.22 |