[Java] reflection ์ ์ด์ฉํ proxy ๊ฐ์ฒด ํ์ฉ(ํ๋ก์ ํจํด)
ํ๊ทธ: Design pattern, Java, Refactoring
์นดํ ๊ณ ๋ฆฌ: Java
- ํ๋ก์ ํจํด์ ๋ํด ์์๋ณธ๋ค.
java.lang.reflect.Proxy
๋ฅผ ์ด์ฉํด ํ๋ก์ ๊ฐ์ฒด(stub)๋ฅผ ์๋ ์์ฑํ๋๋ก ํด๋ณด์.- ๋ฐํ์ ์์ ์ ์์กด๊ฐ์ฒด๋ฅผ ์ฃผ์ ํ๋ค.
Reflection?
Java์ ๋ฆฌํ๋ ์ ์ ๋ฐํ์ ์ ํด๋์ค์ ๋ฉํ๋ฐ์ดํฐ(์: ํ๋, ๋ฉ์๋, ์์ฑ์, ์ฃผ์ ๋ฑ)๋ฅผ ๊ฒ์ฌํ๊ฑฐ๋ ์ํธ ์์ฉํ ์ ์๋ ๊ธฐ๋ฅ์ด๋ค. ์ปดํ์ผ ์ ์ด๋ฆ์ ๋ชฐ๋ผ๋ ํด๋์ค, ๋ฉ์๋ ๋ฐ ํ๋๋ฅผ ๋์ ์ผ๋ก ์กฐ์ํ ์ ์๋ ๋ฐฉ๋ฒ์ ์ ๊ณตํ๋ค.
Class
๋ค์๊ณผ ๊ฐ์ด ๋ฐํ์ ์ ํด๋์ค๋ ์ธํฐํ์ด์ค ์ ๋ณด๋ฅผ ๊ฐ์ ธ์ฌ ์ ์๋ค.
1
2
3
Class<?> clazz = MyClass.class;
Class<?> clazz = obj.getClass();
Class<?> clazz = Class.forName("com.mysql.cj.jdbc.Driver");
Class ์์ธ ์ ๋ณด ํ์ธ
1
2
3
4
5
6
7
8
9
10
11
12
13
Class<?> clazz = MyClass.class;
// ํด๋์ค ์ด๋ฆ ํ์ธ
String className = clazz.getName();
// ์ ๊ทผ์ ํ์ ์ ๋ณด ํ์ธ
int modifiers = clazz.getModifiers();
// super class ์ ๋ณด ํ์ธ
Class<?> superClass = clazz.getSuperclass();
// ๊ตฌํ๋ ์ธํฐํ์ด์ค ์ ๋ณด ํ์ธ
Class<?>[] interfaces = clazz.getInterfaces();
ํ๋ ๋ฐ ๋ฉ์๋ ์ ๋ณด ํ์ธ
1
2
3
4
5
// ๋ชจ๋ ํ๋ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
Field[] fields = clazz.getDeclaredFields();
// ๋ชจ๋ ๋ฉ์๋ ์ ๋ณด ๊ฐ์ ธ์ค๊ธฐ
Method[] methods = clazz.getDeclaredMethods();
ํ๋ ์์
1
2
3
4
5
6
7
// private ํ๋ ์ ๊ทผ
Field privateField = clazz.getDeclaredField("fieldName");
privateField.setAccessible(true); // true ๋ก ๋ฐ๊ฟ์ฃผ๋ฉด private ํ๋์ ์ ๊ทผ ๊ฐ๋ฅํ๋ค.
Object value = privateField.get(obj);
// private ํ๋ ์์
privateField.set(obj, newValue);
๋ฉ์๋ ํธ์ถ
์๋์ฒ๋ผ ๋ฆฌํ๋ ์ ์ ์ด์ฉํด ๋ฉ์๋๋ฅผ ํธ์ถํ ์ ์๋ค.
1
2
3
// ํ๋ผ๋ฏธํฐ ์ ๋ฌ๊ณผ ํจ๊ป ๋ฉ์๋ ํธ์ถ
Method method = clazz.getDeclaredMethod("methodName", parameterTypes);
Object result = method.invoke(obj, arg1, arg2);
๋ฆฌํ๋ ์ ์ ์ธ์ ์ธ๊น?
์ธ์คํด์ค๋ฅผ ์ง์ ์์ฑํด์ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ด ํจ์ฌ ์ง๊ด์ ์ด๊ณ ์ดํด๊ฐ ์ฌ์๋ณด์ด๋๋ฐ ์ ๊ตณ์ด ๋ฆฌํ๋ ์ ์ ์ฌ์ฉํด์ ํธ์ถํ๋๊ฑธ๊น?
ํด๋ผ์ด์ธํธ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ ์ฅ๊ณผ ํ๋ ์์ํฌ/๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ฝ๋๋ฅผ ์์ฑํ๋ ์ ์ฅ์ด ๋ค๋ฅด๊ธฐ ๋๋ฌธ์ด๋ค. ์ธ์คํด์ค๋ฅผ ์ง์ ์์ฑํ๋ค๋ ๊ฒ์ ํ์ ์ด ์ ์ ์ผ๋ก ๊ฒฐ์ ๋๋ค๋ ์๋ฏธ์ด๋ค. ๋ฒ์ฉ์ ์ผ๋ก ์ฌ์ฉ๋์ด์ผ ํ๋ ์์ค์ฝ๋์์๋ ์ ์ฝ ์ฌํญ์ด ๋ง๋ค.
์๋ฅผ ๋ค์ด, ๋ฆฌํ๋ ์
์ ๊ฐ์ฒด๋ฅผ ๋ฐ์ดํธ ์คํธ๋ฆผ์ผ๋ก ๋ณํํด์ผ ํ๋ ์ง๋ ฌํ ๋ฐ ์ญ์ง๋ ฌํ ํ๋ก์ธ์ค์์ ํด๋์ค ๊ตฌ์กฐ๋ฅผ ๋์ ์ผ๋ก ๊ฒ์ฌํ๊ณ ์กฐ์ํ ์ ์๊ฒ ํด์ค๋ค.
Gson
๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ญ์ ๋ฆฌํ๋ ์
์ ์ด์ฉํด ๊ฐ์ฒด์ ํ์
์ ์ถ๋ก ํ๋ค.
๋ํ, ๊ณง ์์๋ณผ Proxy ๊ฐ์ฒด ์์ฑ์๋ ๋ฆฌํ๋ ์
์ด ์ฌ์ฉ๋๋ค. ์คํ๋ง์์๋ ์ด๋ฅผ ๋ ๋ฐ์ ์์ผ AOP(Aspect-Oriented Programming)
๋ฅผ ๊ฐ๋ฅํ๊ฒ ํ๋ค. ์คํ๋ง์์ ์ฃผ๋ก ์ฐ์ด๋ @Transactional
์ด๋
ธํ
์ด์
๋ํ ํ๋ก์๋ฅผ ํตํด ํธ๋์ญ์
์ ๊ด๋ฆฌํ๋ค.
gson ์ ๋ฆฌํ๋ ์ ์ ์ด์ฉํด ํ์ ์ ์์๋ธ๋ค.
์ด์ ๊ธ์์ ์ด๋ ธํ ์ด์ ์ ํตํด ์ธ์ ์ ํ์ธํ๋ ๊ณผ์ ๋ํ ๋ด๋ถ์ ์ผ๋ก ๋ฆฌํ๋ ์ ์ ์ฌ์ฉํ๋ค. HandlerMethodArgumentResolver ๋ ๋ด๋ถ์ ์ผ๋ก ๋ฆฌํ๋ ์ ์ ์ด์ฉํด ์ ๋ณด๋ฅผ ๊ฐ์ ธ์จ๋ค.
๋ฆฌํ๋ ์ ์ฌ์ฉ์ ์ฃผ์ ์ฌํญ
์ค๋ฒํค๋
๋ฆฌํ๋ ์ ์ ๋ฐํ์ ์ ์ ํ ๊ฒ์ฌ ๋ฐ ๋ฉ์๋ ํธ์ถ์ ํฌํจํ๋ ์์ ์ด๊ธฐ ๋๋ฌธ์ ์ผ๋ฐ์ ์ธ ์์ ๋ณด๋ค ๋๋ฆฌ๋ค. ์๊ฐ๊ณผ ๋ฉ๋ชจ๋ฆฌ ์ธก๋ฉด์์ ์ค๋ฒํค๋๊ฐ ๋ฐ์ํ๋ค.
๋ณด์๋ฌธ์
๋ฆฌํ๋ ์ ์ ์ ๊ทผ์ ํ์๋ฅผ ๋ชจ๋ ๋ฌด์ํ๊ธฐ ๋๋ฌธ์ ๋ณด์ ์ทจ์ฝ์ฑ์ด ์๋ค.
์ฝ๋ ๊ฐ๋ ์ฑ
๋ฆฌํ๋ ์ ์ ํฌ๊ฒ ์์กดํ๋ ์ฝ๋๋ ๊ฐ๋ ์ฑ์ด ๋ฎ๊ณ ์ ์ง ๊ด๋ฆฌ๊ฐ ๋ ์ด๋ ต๋ค. ํด๋์ค์ ๋๋ถ๋ถ์ด ๋ฐํ์ ์ ๋์ ์ผ๋ก ๊ฒฐ์ ๋๋ ๊ฒฝ์ฐ ๊ฐ๋ฐ์๋ ํด๋์ค์ ๊ตฌ์กฐ์ ๋์์ ์ดํดํ๋ ๊ฒ์ด ์ด๋ ค์ธ ์ ์๋ค.
์ปดํ์ผ ์์ ์ฑ
๋ฆฌํ๋ ์ ์ ์ปดํ์ผ ํ์ ๊ฒ์ฌ๋ฅผ ์ฐํํ๊ธฐ ๋๋ฌธ์ ์ ์ฌ์ ์ธ ์ค๋ฅ๊ฐ ๋ฐ์ํ ๊ฐ๋ฅ์ฑ์ด ์๋ค.
Proxy?
ํ๋ก์๋ โ๋๋ฆฌโ, โ๋์ โ ์ด๋ผ๋ ๋ป์ ๊ฐ์ง๋ค. ์ด ๊ธ์์๋ ๋ถ์ฐ ์ปดํจํ ํ๊ฒฝ์์ ์๊ฒฉ ๋ฉ์๋๋ฅผ ํธ์ถ์ ๋์ ํด์ฃผ๋ ๊ฐ์ฒด๋ผ๊ณ ๋ณด๋ฉด ๋ ๊ฒ ๊ฐ๋ค.
ํ๋ก์ ํจํด
์์ ๊ท๋ชจ์ Stand-alone ์ดํ๋ฆฌ์ผ์ด์ ์์๋ ๊ตณ์ด ํ๋ก์๊ฐ ์๋ฏธ๊ฐ ์๋ค. ์๋น์ค์ ๊ท๋ชจ๊ฐ ์ปค์ง๊ณ ๋๋ฉ์ธ์ด ๋ง์์ง๋ฉด์ ๋จ์ผ ์๋ฒ์์ ๋ชจ๋ ์์ฒญ์ ์ฒ๋ฆฌํ๊ธฐ ๋ฒ๊ฒ๊ณ , ๋์ ์ฒ๋ฆฌ๊ฐ ํ์ํด์ง๋ ์์ ์ด ๋๋ฉด ๊ฐ ๋๋ฉ์ธ์ ๋ณ๋์ ์๋ฒ๋ก ๋ถ์ฐ์์ผ์ ์ด์ํ๋ ๊ฒ์ด ๋ ํจ์จ์ ์ผ ๊ฒ์ด๋ค.
์ด๋, ๋จ์ผ ์ดํ๋ฆฌ์ผ์ด์ ์์ ๋์ํ๋ ์ฝ๋๋ฅผ ๋ถ๋ฆฌํ๋ ์์ ์ ํด์ผ ํ๋๋ฐ ์ด๋ ๊ฒ ๋๋ฉด ํจ์๊ฐ ์๋ก ์๊ฒฉ ํธ์ถ์ ํ ์ ๋ฐ์ ์๋ค. ์ด๋ฐ ๋ถ์ฐ ์ปดํจํ ํ๊ฒฝ์์ ๊ธฐ์กด์ ๋ฐฉ์๊ณผ ๋์ผํ๊ฒ ํจ์๋ฅผ ํธ์ถํ๋ฉด์๋ ์๊ฒฉ ํธ์ถ์ ๊ธฐ๋ฅ์ ์ถ๊ฐํ๋ ค๋ฉด ์ด๋ป๊ฒ ํด์ผ ๋ ๊น?
ํด๋ผ์ด์ธํธ ์ชฝ์์๋ ํ๋ก์๋ฅผ ์ด์ฉํด ํธ์ถํ๋์ง, ์๋์ง ๊ด์ฌ์ด ์๋ค. ์ํคํ ์ฒ๊ฐ ๋ณ๊ฒฝ๋์ด๋ ๊ธฐ์กด ํธ์ถ ๋ฐฉ์ ๊ทธ๋๋ก ๋์ํด์ผ ํ๋ค. (Open-Closed Principle)
์ด์ ๋ํ ๊ณ ๋ฏผ์ ๊พธ์คํ ์งํ๋์ด ์๋ค. (RPC, RMI, CORBA) (์ต๊ทผ์๋ stub ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํ์ง ์๋ RESTful ๋ฐฉ์์ผ๋ก ํต์ ํ๋ค.)
proxy pattern
stub
๋ถ์ฐ ์ ํ๋ฆฌ์ผ์ด์ ์์ ์คํ ์ ๊ทธ ์์ฒด๋ก ์ ๊ธฐ๋ฅ์ ๋ฐํํ์ง ๋ชปํ์ง๋ง ์๋ ๊ฐ์ฒด๊ฐ ๋ฌด์์ธ์ง ์์๋ผ ์ ์๋ ์ฐธ์กฐ ์ญํ ์ ํ๊ณ , ์ ๊ฐ์ฒด์ ๊ธฐ๋ฅ์กฐ์์ ์์๋ฐ์ proxy ์ญํ ์ ํ๋ ์์ ๊ฐ์ฒด๋ก ์๊ฐํ๋ฉด ๋๋ค. ํด๋ผ์ด์ธํธ์์๋ ๊ธฐ์กด๊ณผ ๋์ผํ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ ๊ฒ์ฒ๋ผ ๋ณด์ด์ง๋ง ์ค์ ํ๋ก์ ๊ฐ์ฒด ๋ด๋ถ์์ ์๊ฒฉ ํธ์ถ์ ํ๊ณ ์๋ ์ ์ด๋ค.
์ค์ ๊ตฌํ ์ stub ์ ๋์๋๋ ์๊ฒฉ ๊ฐ์ฒด(server ์ชฝ์ ์กด์ฌ)์ ๊ฐ์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํด ๋์ ๊ท์น์ ๋์ผํ๊ฒ ๋ง๋ ๋ค.
ํ์ฌ ํ๋ก์ ํธ์ ๊ตฌํ๋ ๋์ ๋ฐฉ์์
- ํด๋ผ์ด์ธํธ์ ์๋ฒ์ ์ฐ๊ฒฐ์ด ์๋ฆฝ๋๋ฉด, proxy ๊ฐ์ฒด(stub)๋ ์๊ฒฉ ๋ฉ์๋ ํธ์ถ์ ํ์ํ ํ๋ผ๋ฏธํฐ๋ค์ ๋ง์ด๋ง(Marshalling) ํ์ฌ ์๊ฒฉ JVM ์ผ๋ก ์ ์กํ ๋ค ์๋ต ๊ฒฐ๊ณผ๋ฅผ ๊ธฐ๋ค๋ฆฐ๋ค.
(ํ์ฌ ํ๋ก์ ํธ์์๋
๋๋ฉ์ธ๋ช
,ํธ์ถํ ํจ์๋ช
,ํจ์ ํธ์ถ์ ํ์ํ ํ๋ผ๋ฏธํฐ
) - ์๋ฒ์ ์ค์ผ๋ ํค(skeleton) ์ ํด๋ผ์ด์ธํธ๊ฐ ๋ณด๋ธ ๋ง์ฌ๋ ํ๋ผ๋ฏธํฐ๋ฅผ ์๋๋๋ก ์ธ๋ง์ด๋ ํ๋ค.
- ์ด ํ๋ผ๋ฏธํฐ๋ฅผ ์ค์ ์๊ฒฉ ๊ฐ์ฒด์๊ฒ ์ ๋ฌํ์ฌ ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
- ํธ์ถ ํ ๊ฒฐ๊ณผ ๊ฐ์ด๋ ์์ธ๋ฅผ ์ค์ผ๋ ํค์๊ฒ ๋๋๋ ค์ค๋ค.
- ์ค์ผ๋ ํค์ ๋ค์ ๊ฒฐ๊ณผ๊ฐ์ด๋ ์์ธ๋ฅผ ๋ง์ฌ๋งํ์ฌ ํธ์ถ์(stub)์๊ฒ ์ ๋ฌํ๋ค.
stub ์ ํตํด ์๊ฒฉ ๋ฉ์๋์ ์ ๊ทผํ๋ค.
skeleton
์คํ ์ ๊ฐ์ฒด ๊ทธ ์์ฒด์ ๋์ผํ ๋น์ฆ๋์ค ๋ฉ์๋๋ฅผ ๊ฐ์ง ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ์ง๋ง, ์คํ ์ ๋ฉ์๋๋ ๋น์ฆ๋์ค ๋ก์ง ์์ฒด๋ฅผ ๋ด๊ณ ์์ง๋ ์์ผ๋ฉฐ, ํด๋ผ์ด์ธํธ๊ฐ ์คํ ์ ๋น์ฆ๋์ค ๋ฉ์๋๋ฅผ ํธ์ถํ๋ฉด ํธ์ถ๋ ๋ฉ์๋ ๋ช ๊ณผ ๋งค๊ฐ๋ณ์๋ก ์ ๋ฌ๋ ๊ฐ๋ค์ด ์คํธ๋ฆผ ํํ๋ก ๋คํธ์ํฌ๋ฅผ ํตํด ์ค์ผ๋ ํค์ ์ ๋ฌ๋๋ค. ํด๋น ์คํธ๋ฆผ์ ์ค์ผ๋ ํค์ด ๋ฐ๊ฒ ๋๋ฉด ์ค์ผ๋ ํค์ ์คํธ๋ฆผ์ ๋ถ์ํ์ฌ ์ด๋ค ๋ฉ์๋๊ฐ ์์ฒญ๋์๋์ง๋ฅผ ํ์ ํ๊ณ , ์๋ฒ์ ์๋ ๊ฐ์ฒด์ ๋น์ฆ๋์ค ๋ฉ์๋๋ฅผ ํธ์ถํ๊ฒ ๋๋ค. ๋ฉ์๋์ ์คํ ๊ฒฐ๊ณผ๊ฐ์ ๋ค์ ์ค์ผ๋ ํค์ ์ํด ์คํ ์ผ๋ก ์ ๋ฌ๋๋ฉฐ, ์คํ ์ ๋ง์น ํด๋น ๋น์ฆ๋์ค ๋ก์ง์ ๋ก์ปฌ ์ปดํจํฐ์์ ์ฒ๋ฆฌํ ๊ฒ์ฒ๋ผ ํด๋ผ์ด์ธํธ ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ฒฐ๊ณผ๊ฐ์ ์ ๋ฌํ๋ค.
reflection ์ผ๋ก proxy ๊ฐ์ฒด(stub) ์๋ ์์ฑํ๊ธฐ
๊ธฐ์กด ์์ค์์๋ stub ๊ฐ์ฒด๋ฅผ ๊ฐ๊ฐ์ ๋๋ฉ์ธ๋ง๋ค ๋ง๋ค์์๋ค. ๊ทธ๋ฌ๋ค๋ณด๋ ๊ตฌํ์ฒด์ ๊ธฐ๋ฅ๊ณผ ์์ค์ฝ๋๊ฐ ๋์ผํ ์ํ์์ ๋๋ฉ์ธ๋ง ๋ฐ๋ DaoImpl
ํด๋์ค๊ฐ ๊ณ์ ์๊ฒจ๋ฌ๋ค.
๊ทธ๋ฆฌ๊ณ ์ด ๊ตฌํ์ฒด๋ค์ ClientApp
์์ ์ปดํ์ผ ์์ ์ ์ฃผ์
ํ๋๋ก ๋ง๋ค์๋ค.
๋๋ฉ์ธ์ด ์๋ก ์๊ธฐ๋ฉด ์ธํฐํ์ด์ค์ ๊ตฌํ์ฒด๋ ์๋ก ๋ง๋ค์ด์ผํ๋ค.
๊ฐ ๋๋ฉ์ธ ๋ ํผ๋ฐ์ค ํ์ ์ ๋ง๋ dao ์ธ์คํด์ค๋ฅผ ์ง์ ์ฃผ์ ํด์ค์ผ ํ๋ค.
newProxyInstance
1
2
// java.lang.reflect.Proxy.class
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
java.lang.reflect.Proxy
ํด๋์ค์๋ newProxyInstance
๋ผ๋ ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋๊ฐ ์กด์ฌํ๋๋ฐ ๋ฐํ์ ์์ ์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ์ค ํ๋ ์ด์์ ์ธํฐํ์ด์ค๋ฅผ ๊ตฌํํ๋ ๋์ ํ๋ก์ ์ธ์คํด์ค๋ฅผ ๋ง๋ค์ด ๋ฐํํด ์ค๋ค.
ํ๋ผ๋ฏธํฐ:
- loader: ํ๋ก์ ํด๋์ค๋ฅผ ์ ์ํ๋ ํด๋์ค ๋ก๋. ํ๋ก์ ํด๋์ค๋ฅผ ๋์ ์ผ๋ก ๋ก๋ํ๋ ์ญํ ์ ๋ด๋นํ๋ค.
- interfaces: ์๋ ์์ฑํ ํด๋์ค๊ฐ ๊ตฌํํด์ผ ํ๋ ์ธํฐํ์ด์ค ๋ชฉ๋ก. ๋ฐฐ์ด ํ์ ์ด๋ค.
- h (InvocationHandler):
InvocationHandler
๊ตฌํ์ฒด๋ฅผ ๋ฃ์ด์ค๋ค. ํ๋ก์ ์ธ์คํด์ค๋ฅผ ์ ๋ฌ๋ฐ์Handler
๊ฐ์ฒด๊ฐ CRUD ๋ฉ์๋๋ฅผ ํธ์ถํ ๋๋ง๋ค ํธ์ถ๋๋ค.
stub (client proxy Dao)
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
public class DaoProxyGenerator {
private String host;
private int port;
private Gson gson;
public DaoProxyGenerator(String host, int port) {
this.host = host;
this.port = port;
gson = new GsonBuilder().setDateFormat("yyyy-MM-dd").create();
}
public <T> T create(Class<T> clazz, String dataName) {
return (T) Proxy.newProxyInstance(DaoProxyGenerator.class.getClassLoader(),
new Class<?>[] {clazz}, (proxy, method, args) -> {
// ์๋ฒ์ ์์ฒญํ ๋๋ง๋ค ์ฐ๊ฒฐํ๋ค.
try (Socket socket = new Socket(host, port);
DataInputStream in = new DataInputStream(socket.getInputStream());
DataOutputStream out = new DataOutputStream(socket.getOutputStream())) {
out.writeUTF(dataName);
out.writeUTF(method.getName());
if (args == null) {
out.writeUTF("");
} else {
out.writeUTF(gson.toJson(args[0]));
}
String code = in.readUTF();
String entity = in.readUTF();
if (!code.equals("200")) {
throw new Exception(entity);
}
Type returnType = method.getGenericReturnType();
if (returnType == void.class) {
return null;
} else {
return gson.fromJson(entity, returnType);
}
} catch (Exception e) {
e.printStackTrace();
throw new DaoException(e);
}
});
}
}
๊ธฐ์กด์ ์ข ์์ฑ์ ์ฃผ์ ํ๋ ๊ณผ์ ๊ณผ ๋ค๋ฅธ์ ์ ํด๋ผ์ด์ธํธ๊ฐ ์ง์ ์ธ์คํด์ค๋ฅผ ์์ฑํ์ง ์๋๋ค๋ ๊ฒ์ด๋ค.
DaoProxyGenerator
๋ผ๋ ํด๋์ค์ ์ ์ ํฉํ ๋ฆฌ ๋ฉ์๋์์ ๋ฐํ์ ์์ ์ ์ธ์คํด์ค๋ฅผ ์์ฑํด ๋ฐํํด ์ค๋ค. ์ด๋ฐ ๋ฐฉ์์ ์ทจํจ์ผ๋ก์จ ์ข ๋ ๋ฎ์ ๊ฒฐํฉ๋๋ฅผ ๊ฐ๊ฒ ๋์๊ณ , dao
๊ฐ์ฒด ์์ฑ ๋ก์ง์ ํ๋์ ํด๋์ค์ ๋ชจ๋ ์บก์ํ ํจ์ผ๋ก์จ ๋์ ์์ง๋๋ฅผ ๊ฐ๊ฒ ๋์๋ค. (low coupling, high cohesion)
๋ง์ฝ ์ํธ์์ฉ(์์, ํฌํจ, ๊ตฌํ ๋ฑ)ํ๋ ๊ฐ์ฒด๋ค์ด ๋ง์์ง๋ฉด ๊ฐ๋ฐ์๊ฐ ๊ทธ ๋ชจ๋ ๊ด๊ณ๋ฅผ ์ผ์ผ์ด ๊ธฐ์ตํ๊ณ ์ฃผ์ ํด ์ค๋ค๋ ๊ฒ์ ๋ถ๊ฐ๋ฅ์ ๊ฐ๊น๋ค.
์คํ๋ง ํ๋ ์์ํฌ๋ ์ด๋ฌํ ๊ณ ๋ฏผ์ ๋ฆฌํ๋ ์ ๊ณผ ํ๋ก์๋ฅผ ํตํด ํด๊ฒฐํ๋ค. ์คํ๋ง์์ DI(Dependency Injection)๋ ์คํ๋ง IoC ์ปจํ ์ด๋์์ ์ด๋ฃจ์ด์ง๋๋ฐ, ์ ํ๋ฆฌ์ผ์ด์ ์ด๋ ํด๋์ค๊ฐ ์๋๋ผ ์ธ๋ถ ์ปจํ ์ด๋์์ ์ฃผ์ ๋๋ค. ๋ณต์กํ ์์กด ๊ฐ์ฒด์ ๋ํ ๋ผ์ดํ์ฌ์ดํด์ ์คํ๋ง์๊ฒ ์์ํ ์ ์๋ ๊ฒ์ด๋ค.
ํ๋ก์๋ AOP(Aspect-Oriented Programming) ๋ฐ ๋ฐํ์ ์ ๋์ ์ผ๋ก ๊ธฐ๋ฅ์ ์ ๊ณตํ๋ ค๋ ๊ธฐํ ๋ค์ํ ๊ฒฝ์ฐ์ ๊ฐ์ ์๋๋ฆฌ์ค์์ ์ ์ฉํ๋ค.
skeleton (ServerApp)
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
// ServerApp.class
public class ServerApp {
...
// skeleton method
void processRequest(DataInputStream in, DataOutputStream out) throws IOException {
System.out.println("[ํด๋ผ์ด์ธํธ ์์ฒญ]");
String dataName = in.readUTF();
String command = in.readUTF();
String value = in.readUTF();
try {
Object dao = daoMap.get(dataName);
if (dao == null) {
throw new RequestException("์์ฒญ ๋ฐ์ดํฐ๊ฐ ์์ต๋๋ค!");
}
System.out.printf("๋ฐ์ดํฐ: %s\n", dataName);
Method commandHandler = findMethod(dao.getClass(), command);
System.out.printf("๋ฉ์๋: %s\n", commandHandler.getName());
Object[] args = getArguments(commandHandler, value);
// ๋ฉ์๋๋ฅผ ํธ์ถํ๋ค.
Object returnValue = commandHandler.invoke(dao, args);
out.writeUTF("200");
out.writeUTF(gson.toJson(returnValue));
System.out.println("ํด๋ผ์ด์ธํธ์๊ฒ ์๋ต ์๋ฃ!");
} catch (RequestException e) {
out.writeUTF("400");
out.writeUTF(gson.toJson(e.getMessage()));
} catch (Exception e) {
out.writeUTF("500");
out.writeUTF(gson.toJson(e.getMessage()));
}
}
}
skeleton(ServerApp) ์ Dao
๊ตฌํ์ฒด๋ค์ ๋ฏธ๋ฆฌ Map
์ ๋ด์๋๋ค๊ฐ stub ๊ฐ์ฒด๋ก๋ถํฐ ๋ง์ฌ๋ง ๋ฐ์ดํฐ๊ฐ ์ ๋ฌ๋๋ฉด ๋ฆฌํ๋ ์
์ ํตํด ํธ์ถํด์ผ ๋ Dao ๊ฐ์ฒด์ ๋ฉ์๋๋ฅผ ์ฐพ์์ ํธ์ถํ๋ค.
ํ์ฌ ํ๋ก์ ํธ ๊ตฌ์กฐ
app-api
1
2
3
4
5
6
7
8
9
10
11
12
app-api
โโโ src
โโโ main
โโโ java
โย ย โโโ bitcamp
โย ย โโโ myapp
โย ย โโโ dao
โย ย โโโ DaoProxyGenerator.java
โโโ resources
โโโ build.gradle
8 directories, 2 files
app-common
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
app-common
โโโ src
โโโ main
โโโ java
โย ย โโโ bitcamp
โย ย โโโ myapp
โย ย โโโ dao
โย ย โย ย โโโ AssignmentDao.java
โย ย โย ย โโโ BoardDao.java
โย ย โย ย โโโ DaoException.java
โย ย โย ย โโโ MemberDao.java
โย ย โโโ vo
โย ย โโโ Assignment.java
โย ย โโโ Board.java
โย ย โโโ Member.java
โโโ resources
โโโ build.gradle
9 directories, 8 files
app-server
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
app-server
โโโ src
โโโ main
โโโ java
โย ย โโโ bitcamp
โย ย โโโ RequestException.java
โย ย โโโ myapp
โย ย โโโ ServerApp.java
โย ย โโโ dao
โย ย โโโ json
โย ย โโโ AbstractDao.java
โย ย โโโ AssignmentDaoImpl.java
โย ย โโโ BoardDaoImpl.java
โย ย โโโ MemberDaoImpl.java
โโโ resources
โโโ assignment.json
โโโ board.json
โโโ build.gradle
โโโ greeting.json
โโโ member.json
9 directories, 11 files
app-client
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
app-client
โโโ src
โโโ main
โโโ java
โย ย โโโ bitcamp
โย ย โโโ menu
โย ย โย ย โโโ AbstractMenu.java
โย ย โย ย โโโ AbstractMenuHandler.java
โย ย โย ย โโโ Menu.java
โย ย โย ย โโโ MenuGroup.java
โย ย โย ย โโโ MenuHandler.java
โย ย โย ย โโโ MenuItem.java
โย ย โโโ myapp
โย ย โย ย โโโ ClientApp.java
โย ย โย ย โโโ handler
โย ย โย ย โโโ HelpHandler.java
โย ย โย ย โโโ assignment
โย ย โย ย โย ย โโโ AssignmentAddHandler.java
โย ย โย ย โย ย โโโ AssignmentDeleteHandler.java
โย ย โย ย โย ย โโโ AssignmentListHandler.java
โย ย โย ย โย ย โโโ AssignmentModifyHandler.java
โย ย โย ย โย ย โโโ AssignmentViewHandler.java
โย ย โย ย โโโ board
โย ย โย ย โย ย โโโ BoardAddHandler.java
โย ย โย ย โย ย โโโ BoardDeleteHandler.java
โย ย โย ย โย ย โโโ BoardListHandler.java
โย ย โย ย โย ย โโโ BoardModifyHandler.java
โย ย โย ย โย ย โโโ BoardViewHandler.java
โย ย โย ย โโโ member
โย ย โย ย โโโ MemberAddHandler.java
โย ย โย ย โโโ MemberDeleteHandler.java
โย ย โย ย โโโ MemberListHandler.java
โย ย โย ย โโโ MemberModifyHandler.java
โย ย โย ย โโโ MemberViewHandler.java
โย ย โโโ util
โย ย โโโ AnsiEscape.java
โย ย โโโ Prompt.java
โโโ resources
โโโ build.gradle
13 directories, 26 files
์ข ๋ ์ฐพ์๋ณผ ๋ด์ฉ
์คํ๋ง์์ ํ๋ก์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฐฉ๋ฒ
- JDK Dynamic Proxy
- CGLib
๋๊ธ๋จ๊ธฐ๊ธฐ