๐ฅ [Spring] FactoryMethod ํจํด & Spring DI
MVC vs Front-Controller
MVC
์ FrontController
์ ์ฐจ์ด๋ฅผ ์์๋ณด์
MVC Pattern
์ฅ์
๋น์ฆ๋์ค ๋ก์ง์ด ๊ฐ๊ฐ ๋ชจ๋ํ ๋์ด ํธ์ถ์ด ๋์ด์ง
์๊ตฌ์ฌํญ์ด ๋ณ๊ฒฝ๋๋๋ผ๋ ๋ค๋ฅธ ์ปดํฌ๋ํธ์ ๋ผ์ง์น์ง ์์
ํ์ฅ์ฑ์ด ์๋ค
๋จ์
ํ๋์ ์๊ตฌ์ฌํญ (Business Logic)์ ์ฒ๋ฆฌํ๊ธฐ ์ํด์ ์ผ์ผํ ๋ง๋ค์ด์ค์ผ ํจ
Front-Controller
์ฅ์
ํ๋์ ์๋ธ๋ฆฟ์ด ๋ชจ๋ ์์ฒญ์ ๋ค ์ฒ๋ฆฌ
๋จ์
ํ๋์ Servlet ์์ ๋ชจ๋ Business Logic ์ Method Block ์ผ๋ก ๋ค ์ฒ๋ฆฌ
๋งค์ฐ ๋ฌด๊ฑฐ์ด Controller ๊ฐ ์์ฑ ๋จ
Factory Method Pattern
MVC
์FrontController
์ ์ฅ์ ์ ๋ชจ์๋์ ๊ฒ
Client๋ก ๋ถํฐ ์์ฒญ์ด ๋ค์ด์ค๋ฉด ๊ฐ์ฅ ๋จผ์ FrontController๊ฐ ๋ฐ๊ฒ ๋๋๋ฐ
์ฌ๊ธฐ์ ์ด๋ค ์์ฒญ์ด ์๋์ง command ๋ณ์์ ๋ฃ์ด์ฃผ๊ณ ControllerFactory์ ๋ฃ์ด์ค๋ค.
ControllerFactory
๋ ๋ง ๊ทธ๋๋ก Controller
๋ฅผ ๋ง๋ค์ด์ฃผ๋ ๊ณต์ฅ์ด๋ผ๋ ์๋ฏธ ์ด๋ค.
ControllerFactory๋ command๋ฅผ ๋ณด๊ณ ์ด๋ค ํด๋น command์ ๋ฐ๋ฅธ Controller
๋ฅผ ๋ง๋ค์ด FrontController
์๊ฒ ์ ๋ฌํด์ค๋ค.
๊ทธ๋ฌ๋ฉด ํด๋น Controller
์ Component
๋ฉ์๋ ์ค handleRequest()
๋ฅผ ํธ์ถํ๊ณ ๊ฒฐ๊ณผ ํ์ด์ง๋ฅผ ์ป์ด
FrontController
๋ก ๋ณด๋ด๊ณ FrontController
์์๋ forward
๋ Redirect
๋ฅผ ํด์ ๋ค๋น๊ฒ์ด์
์ ํด์ค๋ค.
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
// frontController
package web.client;
import java.util.Scanner;
import web.controller.Controller;
import web.factory.ControllerFactory;
/*
* ๋์ค์ Servlet์ญํ
* FrontController๊ฐ ๋๋ค.
*/
public class FrontController {
public static void main(String[] args) {
// ๋ธ๋ผ์ฐ์ ํผ์์ ๋ฐ์ ๊ฐ์...
Scanner sc = new Scanner(System.in);
System.out.println(">>>Command ๊ฐ์
๋ ฅ");
String command = sc.next();
//ControllerFactory๋ก ๋๊น
Controller controller = ControllerFactory.getInstance().createController(command);
controller.handleRequest();
//์ง๊ธ์ ๊ฒฐ๊ณผํ์ด์ง ๋ค๋น๊ฒ์ด์
์ํ๊ณ ์ฝ์์์ ํ์ธ
}
}
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
//factory controller
package web.factory;
import web.controller.Controller;
import web.controller.FindController;
import web.controller.LoginController;
import web.controller.RegisterController;
import web.controller.UpdateController;
/*
* Controller๋ฅผ ๋ง๋๋ ๊ณต์ฅ
* ์ด๊ณณ์์ Register, Find, Update, Login.,... Controller๋ฅผ ๊ฐ๊ฐ ์์ฑํ๋ค.
* ::
* 1) 4๊ฐ์ Controller๋ฅผ ์์ฑ --> ControllerFactoryrk 4๊ฐ ํ์??
* 2) 4๊ฐ์ Controller์์ฑ --> ControllerFactory๊ฐ 1๊ฐ ํ์?
*
* ControllerFactory ์ฑ๊ธํค ํจํด์ผ๋ก ์์ฑ
*/
public class ControllerFactory {
private static ControllerFactory factory = new ControllerFactory();
private static Controller controller;
private ControllerFactory() {
System.out.println("Creating ControllerFactory...");
}
public static ControllerFactory getInstance() {
return factory;
}
//ํด๋ผ์ด์ธ๋์ ์์ฒญ์ ๋ฐ๋ผ์ ์๋ก ๋ค๋ฅธ Controller๋ฅผ ๊ณต์ฅ์์ ์์ฑํด๋ธ๋ค.
public Controller createController(String command) {
if(command.equals("register")) {
controller = new RegisterController();
System.out.println("RegisterController...Creating...OK");
}
else if(command.equals("find")) {
controller = new FindController();
System.out.println("FindController...Creating...OK");
}
else if(command.equals("update")) {
controller = new UpdateController();
System.out.println("UpdateController...Creating...OK");
}
else if(command.equals("login")) {
controller = new LoginController();
System.out.println("LoginController...Creating...OK");
}
return controller;
}
}
FrontController๋ก ์ป์ command๋ฅผ ๋ฐ์์ ํด๋น command์ ๋ฐ๋ฅธ Controller๋ฅผ ์์ฑํ๋ค.
Controller๋ฅผ ์์ฑํ๊ณ Controller๋ฅผ ํธ์ถํ FrontController๋ก ๋์๊ฐ๋ค.
1
2
3
4
5
//ControllerFactory๋ก ๋๊น
Controller controller = ControllerFactory.getInstance().createController(command);
//handleRequest ํธ์ถ
controller.handleRequest();
์ด์ handleRequest๋ฅผ ํธ์ถํ๋ค.
Controller ํ์ ์ Interface ์ด๋ค.
1
2
3
4
5
package web.controller;
//Template ๊ธฐ๋ฅ๋ง์ผ๋ก ๊ตฌ์ฑ...
public interface Controller {
String handleRequest();
}
์ฆ, ๊ฐ ๊ธฐ๋ฅ๋น Controller๋ฅผ ๊ตฌํํด ์กด์ฌํ๋ ๊ฒ์ด๋ค.
๊ทธ๋ฌ๋ฉด command์ ๋ฐ๋ฅธ Controller๋ฅผ return ๋ฐ๊ณ ๊ทธ Controller๊ฐ handleRequest()
๋ฅผ ํธ์ถํ๋ฉด
๊ธฐ๋ฅ์ ๋ง๋ handleRequest()
๊ฐ ์๋ํ๋ ๊ฒ์ด๋ค.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package web.controller;
public class FindController implements Controller{
@Override
public String handleRequest() {
/*
Controller์ ์ญํ
1. ํผ๊ฐ ๋ฐ์์
2. vo ์์ฑ
3. dao ๋ฆฌํด ๋ฐ๊ณ
4. business logic ํธ์ถ
5. ๋ค๋น๊ฒ์ด์
//MVC ํจํด์์๋ Controller ์ญํ ์ Servlet ๋จ์๊ฐ ํ๊ณ
//FrontController์์๋ ๋ฉ์๋ ๋จ์๊ฐ ํ๊ณ
//์ง๊ธ์ ์ธํฐํ์ด์ค ์์๋ฐ์ ์๋ฐ ํด๋์ค์์ ํ๊ณ ์๋ค.
* ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์ฌ์ฌ์ฉ์ฑ์ด ๋์ ์๋ฐ ํด๋์ค๋ฅผ ์ปดํฌ๋ํธ๋ผ๊ณ ํ๋ค.
*/
System.out.println("FIndController... Find Member");
return "find_ok.jsp";
}
}
์ค์ํ ์ ์ ์ง๊ธ๊น์ง ์ด๋ฌํ Controller์ ์ญํ ์ MVC์์๋ Servlet์ด ํด์ฃผ์๊ณ ,
FrontController ํจํด์์๋ ํ๋์ Servlet ์์ ๋ฉ์๋๋ค์ด ํด์ฃผ์๋ค.
FactoryMethod ํจํด์์๋ Controller ์ธํฐํ์ด์ค๋ฅผ ์์๋ฐ์ ์๋ฐ ํด๋์ค์์ ํ๊ณ ์๋ค.
์ด๋ฌํ ์๋ฐ ํด๋์ค๋ฅผ Component(์ปดํฌ๋ํธ) ๋ผ๊ณ ํ๋ค.
Spring
์คํ๋ง ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ ์์ ๊ฐ์ด ๋ชจ๋ํ ๋์ด ์๋ค.
์ฐ๋ฆฌ๋ ๋จผ์ Core Container
๋ฅผ ์ดํด๋ณธ๋ค.
Spring DI(Core Container)
Container
๋ ๋ ๊ฐ์ง๋ก ๋๋๋๋ฐ Presentation Layer
์ Business Logic Layer
๋ก ๋๋๋ค.
์ด ๋ ๊ฐ๋ฅผ ํฉ์น๋ฉด 2 Architecture Layer
๋ผ๊ณ ํจ
Business Logic Layer
์์ ๊ฐ์ฅ ์ค์ํ ๊ฒ์ MemberDAOImpl
์ธ๋ฐ
๊ฐ๋ฐ์๊ฐ ์ง์ ๋ง๋๋ ๊ฒ์ด ์๋ DI
๊ฐ ์์ฑํ๋ ๊ฒ์
Container ๋ DD
ํ์ผ์ ์ฝ๊ณ Servlet
์ ์์ฑํจ (Components
๋ฅผ ์์ฑํ๋ ๊ฒ์ด ์๋)
์ด๋ฌํ DAOImpl
์ DB
์ ์ฐ๊ฒฐํ๋ ํ๋ ์์ํฌ๊ฐ JDBC Framework
์ด๋ค. (MyBatis, Hybernateโฆ)
Presentation Layer
์ ํ๋ ์์ํฌํ ํ ๊ฒ์ SpringMVC
๋ผ๊ณ ํ๋ค.
DI(Dependency Injection)
Container
๊ฐ ์๋ํ๋ฉด dd
(web.xml =servlet ๋งคํ ์ ๋ณด๋ก ์ด๋ฃจ์ด์ ธ ์์) ๋ฅผ ์ฝ๊ณ Servlet
์ ๋ง๋ ๋ค.
์ธ๊ฐ์ ์ญํ ์ ์ฃผ๋ฌธ์ ์์ฑ์ด๊ณ ๊ธฐ๊ณ๋ ๋ณต์กํ ์์ ์ ํ๋ค.
Container
๊ฐ Client
๋ก ์์ฒญ์ ๋ฐ์ผ๋ฉด Factory
์๊ฒ ์๋ฆฌ๊ณ Factory
๋ component
๋ฅผ ๋ง๋ ๋ค.
๋ง๋ค์ด์ง Component
๋ Business Logic
์ ํธ์ถํ๋ค.
์ด๋ฌํ Component
๋ฅผ ๋ง๋๋ Factory
๋ฅผ DI Container๋ผ๊ณ ํ๋ค.
DI Container
์ค์ BeanFactory๋ก ๋ง๋ค์์ง๋ง ์ด๋ฒ์ ApplicationContext๋ฅผ ์ฌ์ฉํ๋ค.
DI Container
๋ ๋งค์ฐ ๊ฒฝ๋ํ Container
์ด๊ธฐ ๋๋ฌธ์ ๋ถ๋ด์ด ์๋ค.
DI Container
๋ WAS์ ์ํด ํธ์ถ๋๋๋ก ๋์ด์๋ค.
DI Container
๋ ์ฃผ๋ฌธ์๋ฅผ ์ฝ๊ณ Component
๋ฅผ ๋ง๋ ๋ค.
์ด์ ๊ธฐ์ค์ผ๋ก ์ฃผ๋ฌธ์๋ diceservice.xml ์ด๋ค.
๋จผ์ vo
์ธ User class ์์ฑ
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
package spring.service.domain;
public class User implements Serializable {
///Field
private String userId; /* ํ์ ID */
private String password; /* ๋น๋ฐ๋ฒํธ */
private int age; /* ๋์ด */
///Constructor
public User() {
System.out.println("\n::"+getClass().getName()+" ๋ํดํธ ์์ฑ์....");
}
public User(int age, String userId) {
System.out.println("\n::"+getClass().getName()+" age,userId ์ธ์ ๋ฐ๋ ์์ฑ์....");
this.age = age;
this.userId = userId;
}
public User(int age, String password, String userId) {
System.out.println("\n::"+getClass().getName()+"age,password,userId ์ธ์ ๋ฐ๋ ์์ฑ์");
this.age = age;
this.password = password;
this.userId = userId;
}
///Method (getter/setter)
public String getUserId(){
return this.userId;
}
public void setUserId( String userId ){
System.out.println("::"+getClass().getName()+".setUserId()");
this.userId= userId;
}
public String getPassword(){
return this.password;
}
public void setPassword( String password ){
System.out.println("::"+getClass().getName()+".setPassword()");
this.password= password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("::"+getClass().getName()+".setAge()");
this.age = age;
}
@Override
public String toString() {
return "UserVO [userId=" + userId + ", password=" + password + ", age="+ age + "]";
}
}//end of class
1
2
BeanFactory factory =
new XmlBeanFactory(new FileSystemResource("./src/main/resources/config/userservice01.xml"));
๋จผ์ BeanFactory
๋ฅผ ํตํด DI ์ปจํ
์ด๋๋ฅผ ์์ฑํด์ค๋ค.
์ด์ userservice01.xml ์ฃผ๋ฌธ์๋ฅผ ์ฝ๊ณ bean์ ์์ฑํด์ค๋ค.
1
2
User user01 = (User)factory.getBean("user01");
System.out.println(user01);
id๊ฐ โuser01โ ์ธ bean์ ์์ฑํ๋ค.
์ด์ ํด๋นํ๋ ์ฃผ๋ฌธ์๋ฅผ ์ดํด๋ณธ๋ค.
- setter ์ฃผ์ :: ๋จ์ ํ๋ผ๋ฏธํฐ ๊ฐ ์ฃผ์
User user01 = new User()
user01.setUserId(โ01์ ์ โ)
user01.setAge(โ01โ)
1
2
3
4
<bean id="user01" class="spring.service.domain.User">
<property name="userId" value="01์ ์ "/>
<property name="age" value="01"/>
</bean>
์์๋๋ก ๋ํดํธ ์์ฑ์ โ setUserId() โ setAge() ๊ฐ ํธ์ถ๋์๋ค.
DI Container ์ Bean ์์ฑ ์์
DI Container์์ ๋น ์์ฑ ์์ ์ ์ธ์ ์ผ๊น?
- ์ฃผ๋ฌธ์ ์ฝ์ ๋ง์ ๋น์ ๋ง๋๋์ง? (preloading)
- getBean()ํ ๋ (์์ฒญ ํ ๋) ๋ง๋๋์ง? (lazy loading)
1
2
3
4
5
6
BeanFactory factory =
new XmlBeanFactory(new FileSystemResource("./src/main/resources/config/userservice01.xml"));
System.out.println("\n=============================================================================");
User user01 = (User)factory.getBean("user01");
System.out.println(user01);
::spring.service.domain.User ๋ํดํธ ์์ฑ์โฆ
::spring.service.domain.User.setUserId()
::spring.service.domain.User.setAge()
UserVO [userid=01์ ์ , password=null, age=1]
์ Factory๋ BeanFactory
๋ฅผ ์ฌ์ฉํ์๋ค.(=lazy loading)
๋ค๋ฅธ Factory์ธ ApplicationContext
๋ฅผ ์ฌ์ฉํด๋ณด๋ฉด
1
2
3
4
5
ApplicationContext factory = new ClassPathXmlApplicationContext("/config/userservice.xml");
System.out.println("\n=============================================================================");
User user01 = (User)factory.getBean("user01");
System.out.println(user01);
::spring.service.domain.User ๋ํดํธ ์์ฑ์โฆ
::spring.service.domain.User.setUserId()
::spring.service.domain.User.setAge()
::spring.service.domain.User ๋ํดํธ ์์ฑ์โฆ
::spring.service.domain.User.setUserId()
::spring.service.domain.User.setAge()
::spring.service.domain.User.setPassword()
::spring.service.domain.User ๋ํดํธ ์์ฑ์โฆ
::spring.service.domain.UserAge,password,userId ์ธ์ ๋ฐ๋ ์์ฑ์
::spring.service.domain.UserAge,password,userId ์ธ์ ๋ฐ๋ ์์ฑ์
==========================================
UserVO [userId=01์ ์ , password=null, age=1]
์์ ๊ฐ์ด ํ์ฌ ์ฃผ๋ฌธ์์ ์์ฑ๋์ด์๋ ๋ชจ๋ bean์ ๋ง๋ค์ด ๋๊ณ DI Container
์ ์ ์ฅํด๋๊ณ
getBean()
์ด ํธ์ถ๋๋ฉด ๋ฏธ๋ฆฌ ๋ง๋ค์ด ๋์๋ bean๋ง return ํด์ค๋ค.