[JAVA] Annotation๊ณผ Reflections ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ก ์๋ฐ ๋น ๊ด๋ฆฌํ๊ธฐ
Java Annotation(์๋ฐ ์ด๋ ธํ ์ด์ )
์ด๋ ธํ ์ด์ ์ ์ปดํ์ผ, ๋ฐฐํฌ, ์คํ ์ ์ฐธ์กฐํ ์ ์๋ ํน๋ณํ ์ฃผ์์ด๋ผ๊ณ ํ ์ ์๋ค. ์ด๋ ธํ ์ด์ ์ ์ฌ์ฉํ๋ฉด ํด๋์ค, ํ๋, ๋ฉ์๋์ ๋ถ๊ฐ ์ ๋ณด๋ฅผ ๋ฑ๋กํ ์ ์๋ค.
์ด๋ ธํ ์ด์ ์ ์ด์ฉํด์ ์น ์ดํ๋ฆฌ์ผ์ด์ ์ด ์์๋ ๋ ์์ฑ์ด ํ์ํ ๊ฐ์ฒด๋ฅผ ๊ด๋ฆฌํ ์ ์๋๋ก ํด๋ณด์.
์ด๋ ธํ ์ด์ ์ ์
Component.java
1
2
3
4
5
6
7
8
9
|
/*์ด๋
ธํ
์ด์
์ ์ง ์ ์ฑ
- RetentionPolicy.RUNTIME:
* ํด๋์ค ํ์ผ์ ๊ธฐ๋ก๋จ
* ์คํ ์์ ์ ์ง๋จ
* ์คํ ์ค ํด๋์ค์ ๊ธฐ๋ก๋ ์ด๋
ธํ
์ด์
๊ฐ ์ฐธ์กฐ ๊ฐ๋ฅ
* */
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
String value() default "";
}
|
cs |
์ด๋ ธํ ์ด์ ์ ์์ ๊ฐ์ด ์ ์ํ๋ค.
์ด๋ ธํ ์ด์ ๋ฌธ๋ฒ์ ์ธํฐํ์ด์ค์ ๋น์ทํ๋ค.
interface ํค์๋ ์์ '@'๊ฐ ๋ถ๋๋ค.
์ธํฐํ์ด์ค์์ ๋ฉ์๋๋ฅผ ์ ์ํ๋ ๊ฒ ์ฒ๋ผ ์ด๋ ธํ ์ด์ ์์๋ ์์ฑ์ ์ ์ํ๋ค.
์์ฑ ์ค value()๋ ์์ฑ ์ด๋ฆ์ ์๋ตํ ์ ์๋ค.
@Component(value="์์ฑ๊ฐ") = @Component("์์ฑ๊ฐ")
default ํค์๋๋ก ์์ฑ์ ๊ธฐ๋ณธ๊ฐ์ ์ค์ ํ ์ ์๋ค.
์ง๊ธ์ ์์ฑ๊ฐ์ ์ง์ ํ์ง ์์ผ๋ฉด ๋น ๋ฌธ์์ด("")์ด ๊ธฐ๋ณธ๊ฐ์ด ๋๋๋ก ํ์๋ค.
@Retention() - ์ด๋ ธํ ์ด์ ์ ์ง ์ ์ฑ
์ด๋ ธํ ์ด์ ์ ์ ์ํ ๋๋ @Retention()์ผ๋ก ๋ฐ๋์ ์ด๋ ธํ ์ด์ ์ ์ ์ง ์ ์ฑ ์ ์ง์ ํด์ผํ๋ค.
์ด๋ ธํ ์ด์ ์ ์ง ์ ์ฑ ์ ์ด๋ ธํ ์ด์ ์ ๋ณด๋ฅผ ์ธ์ ๊น์ง ์ ์งํ ๊ฒ์ธ์ง ์ค์ ํ๋ ๋ฌธ๋ฒ์ด๋ค.
์์ ์ฝ๋์ฒ๋ผ ์ด๋ ธํ ์ด์ ์ ์ง ์ ์ฑ ์ RUNTIME์ผ๋ก ์ง์ ํ๋ฉด ์คํ ์ค์๋ @Component ์ด๋ ธํ ์ด์ ์ ์์ฑ๊ฐ์ ์ฐธ์กฐํ ์ ์๋ค.
์ด๋ ธํ ์ด์ ์ ์ง ์ ์ฑ | ์ค๋ช |
Retention.SOURCE | ์์ค ํ์ผ์์๋ง ์ ์ง๋๊ณ ์ปดํ์ผ ์ ์ ๊ฑฐ๋จ |
Retention.CLASS (๊ธฐ๋ณธ ์ ์ฑ ) | ํด๋์ค ํ์ผ์ ๊ธฐ๋ก๋๊ณ ์คํ ์์๋ ์ ์ง๋์ง ์์ |
Retention.RUNTIME | ํด๋์ค ํ์ผ์ ๊ธฐ๋ก๋๊ณ ์คํ ์์๋ ์ ์ง๋จ ์คํ ์ค ํด๋์ค์ ๊ธฐ๋ก๋ ์ด๋ ธํ ์ด์ ๊ฐ์ ์ฐธ์กฐํ ์ ์์ |
์ด๋ ธํ ์ด์ ์ ์ฉ
์ดํ๋ฆฌ์ผ์ด์ ์์ ์ Component ์ด๋ ธํ ์ด์ ์ด ์ง์ ๋ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ค๋นํ๋๋ก ํ ๊ฒ์ด๋ค.
์ดํ๋ฆฌ์ผ์ด์ ์์ ์ ๊ฐ์ฒด๋ฅผ ์์ฑํ ํด๋์ค์ ์ด๋ ธํ ์ด์ ์ ์ ์ธํ๋ค.
์ ์ธ ๋ฐฉ๋ฒ์ ํด๋์ค ์ ์ธ๋ถ ์์ @์ด๋ ธํ ์ด์ ๋ช ("์์ฑ๊ฐ")๊ณผ ๊ฐ์ด ์์ฑํด์ฃผ๋ฉด ๋๋ค.
1
2
3
|
@Component("/auth/login.do")
public class LogInController implements Controller, DataBinding {
...
|
cs |
์ปจํธ๋กค๋ฌ์ ์๋ธ๋ฆฟ URL์ ์์ฑ๊ฐ์ผ๋ก ํ์ฌ ์ด๋ ธํ ์ด์ ์ ์ ์ธํด์ฃผ์๋ค.
Reflections ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ค๋น
Reflections๋ ๊ตฌ๊ธ ์ฝ๋ ์ฌ์ดํธ์ ๋ฑ๋ก๋ ์คํ ์์ค ํ๋ก์ ํธ์ด๋ค. ์ด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ด์ฉํ๋ฉด ์๋ฐ ๋ฆฌํ๋์ API๋ณด๋ค ๋ ์ฝ๊ณ ํธํ๊ฒ ํด๋์ค๋ฅผ ์ฐพ๊ณ ์ ๋ณด๋ฅผ ์ถ์ถํ ์ ์๋ค.
https://code.google.com/archive/p/reflections/downloads ์์ Reflections ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๋ค์ด๋ก๋ ๋ฐ์ ์ ์๋ค.
Downloads ํ์ด์ง์์ reflections-0.9.9-RC1-uberjar.jar, reflections-0.9.9-RC1.jar ์ ๋ค์ด๋ก๋ ๋ฐ๋๋ค.
reflections-0.9.9-RC1.jar๋ Reflections ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ด๊ณ reflections-0.9.9-RC1-uberjar.jar์๋ ์์กด ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ค์ด ๋ค์ด์๋ค.
reflections-0.9.9-RC1.jar๋ ๊ทธ๋๋ก ๋๊ณ reflections-0.9.9-RC1-uberjar.jar๋ ์์ถ์ ํ์ด๋๋ค.
reflections-0.9.9-RC1.jar์ reflections-0.9.9-RC1-uberjar.jar ์์ jarํ์ผ๋ค์ ํ๋ก์ ํธ์ ์ถ๊ฐํด์ค๋ค.
๊ฐ์ฒด ์์ฑ ๋ฉ์๋ ๊ตฌํ
์น ์ดํ๋ฆฌ์ผ์ด์ ์ด ์์๋ ๋ ์์ฑ๋๋ ํด๋์ค์ @Component ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ค.
์ฐธ๊ณ ๋ก ํฐ์บฃ์ ๊ฒฝ์ฐ ์น ์ดํ๋ฆฌ์ผ์ด์ ์ด ์์๋ ๋ ServletContextListener ๊ตฌํ์ฒด์ contextInitialized() ๋ฉ์๋๊ฐ ํธ์ถ๋๋ค. ์์ธํ ๊ฒ์ ์๋ ๋งํฌ๋ฅผ ์ฐธ๊ณ ํ์.
์ฐธ๊ณ : ServletContextListener๋ก DB ์ปค๋ฅ์ , 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
|
Map<String, Object> objTable = new Hashtable<>();
// ๊ฐ์ฒด๋ฅผ ๊บผ๋ผ getter
public Object getBean(String key) {
return objTable.get(key);
}
/**
* classpath๋ฅผ ๋ค์ ธ์ Component ์ด๋
ธํ
์ด์
์ด ์ง์ ๋ ํด๋์ค๋ฅผ ์ฐพ์๋ค ํด๋น ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์ค๋นํ๋ค.
* ์์ฑ๋ ๊ฐ์ฒด๋ ๊ฐ์ฒด ํ
์ด๋ธ์ ๋ด๋๋ค.
* ์คํ์์ค ๋ผ์ด๋ธ๋ฌ๋ฆฌ Reflections ์ฌ์ฉ: ์๋ฐ ๋ฆฌํ๋์
API๋ณด๋ค ์ฌ์ฉํ๊ธฐ ์ฝ๊ณ ํธํจ
* @throws Exception
*/
private void prepareAnnotationObjects() throws Exception {
// Reflections ํด๋์ค๋ ์ํ๋ ํด๋์ค๋ฅผ ์ฐพ๊ธฐ ์ํด ์ฌ์ฉ
// ํ๋ผ๋ฏธํฐ๊ฐ์ ํด๋์ค๋ฅผ ์ฐพ์๋ ์ถ๋ฐ ํจํค์ง
// "" -> classpath ๋ชจ๋ ํจํค์ง ๊ฒ์
Reflections reflector = new Reflections("");
// getTypesAnnotatedWith():
// ํ๋ผ๋ฏธํฐ๊ฐ์ผ๋ก ๋๊ธด ์ด๋
ธํ
์ด์
์ด ๋ถ์ ํด๋์ค๋ฅผ ์ฐพ๋๋ค.
// ๋ฐํ๊ฐ: @Component ์ด๋
ธํ
์ด์
์ด ์ ์ธ๋ ํด๋์ค ๋ชฉ๋ก
Set<Class<?>> list = reflector.getTypesAnnotatedWith(Component.class);
String key = null;
for(Class<?> clazz: list) {
// getAnnotation(): ํด๋์ค๋ก๋ถํฐ ์ด๋
ธํ
์ด์
์ถ์ถ
key = clazz.getAnnotation(Component.class).value();
objTable.put(key, clazz.getDeclaredConstructor().newInstance());
System.out.println(clazz.getName() + "(" + key + ") -> ๊ฐ์ฒด ์ค๋น ์๋ฃ");
}
}
|
cs |
๊ฒฐ๊ณผ ํ์ธ์ ์ํด ์ถ๋ ฅ๋ฌธ์ ์์ฑํด๋์๋ค.
1) Reflections
Reflections ์์ฑ์์ ๋๊ฒจ์ฃผ๋ ํ๋ผ๋ฏธํฐ ๊ฐ์ ํด๋์ค๋ฅผ ์ฐพ์๋์ ์ถ๋ฐ ํจํค์ง์ด๋ค. ํ๋ผ๋ฏธํฐ ๊ฐ์ด "com.atoz_develop"์ด๋ฉด com.atoz_develop ํจํค์ง์ ๊ทธ ํ์ ํจํค์ง๋ฅผ ๋ชจ๋ ์ฐพ๋๋ค. ๋น ๋ฌธ์์ด์ ๋๊ธฐ๋ฉด ์๋ฐ classpath์ ์๋ ๋ชจ๋ ํจํค์ง๋ฅผ ์ฐพ๋๋ค.
2) getTypesAnnotatedWith()
์ด ๋ฉ์๋๋ฅผ ํธ์ถํ ๋ ์ด๋ ธํ ์ด์ ์ ํด๋์ค๋ฅผ ํ๋ผ๋ฏธํฐ๋ก ๋๊ฒจ ํด๋น ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ์ฐพ์ ์ ์๋ค.
getTypesAnnotatedWith(Component.class)์ ๊ฐ์ด ํธ์ถํ๋ฉด @Component ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํด๋์ค๋ฅผ ์ฐพ๋๋ค.
๋ฐํ๊ฐ์ ํด๋น ์ด๋ ธํ ์ด์ ์ด ์ ์ธ๋ ํด๋์ค ๋ชฉ๋ก์ด๋ค.
3) getAnnotation().value()
getAnnotation()์ ํตํด ์ด๋ ธํ ์ด์ ์ ์ถ์ถํ๋ค.
์ด๋ ธํ ์ด์ ์ ์ถ์ถํ๋ฉด ํด๋น ์ด๋ ธํ ์ด์ ์ ์ ์๋ ๋ฉ์๋(์์ฑ)์ ํธ์ถํด์ ์์ฑ ๊ฐ์ ๊บผ๋ผ ์ ์๋ค.
Component ์ด๋ ธํ ์ด์ ์๋ value() ์์ฑ์ด ์ ์๋์ด ์์ผ๋ฏ๋ก value()๋ฅผ ํธ์ถํด์ value()์ ์ค์ ๋ ๊ฐ์ ๊บผ๋ผ ์ ์๋ค.
์ด๋ ๊ฒ ๊บผ๋ธ ๊ฐ์ key๋ก ํ์ฌ ํ์ํ ๊ณณ์์ ์ฌ์ฉํ ์ ์๋๋ก ๊ฐ์ฒด๋ฅผ ์ ์ฅํ๋ค.
์ด์ ํฐ์บฃ์ ๊ตฌ๋ํ์ฌ ๊ฒฐ๊ณผ๋ฅผ ํ์ธํด๋ณด์.
์์ ๊ฐ์ด ํฐ์บฃ ๊ตฌ๋์ด ์๋ฃ๋๋ฉด Component ์ด๋ ธํ ์ด์ ์ ์ ์ธํ ํด๋์ค์ ๊ฐ์ฒด๋ฅผ ์์ฑํ๋ ๋ฉ์๋๊ฐ ํธ์ถ๋๋ฉฐ ๊ฐ์ฒด๊ฐ ์ค๋น๋๋ค.
์ด๋ ๊ฒ ํจ์ผ๋ก์จ ์น ์ดํ๋ฆฌ์ผ์ด์ ์์ ์ ์ค๋นํด์ผํ ๊ฐ์ฒด๊ฐ ์ถ๊ฐ๋๋ฉด @Component ์ด๋ ธํ ์ด์ ์ ์ ์ธํด์ฃผ๊ธฐ๋ง ํ๋ฉด ๋๋ค.
'Javaยท๏ปฟServletยท๏ปฟJSP' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
try-with-resource ๋ฌธ๋ฒ์ ์ฌ์ฉํ JDBC ํ๋ก๊ทธ๋๋ฐ ์์ ์ฝ๋ (0) | 2020.03.11 |
---|---|
[JAVA ๋์์ธ ํจํด] static class์ Builder Pattern(๋น๋ ํจํด) (0) | 2020.03.09 |
JAVA ์น ํ๋ก์ ํธ์์ Properties ํ์ผ ํ์ฉํ๊ธฐ (0) | 2020.02.20 |
๋ฆฌํ๋์ API๋ฅผ ์ด์ฉํ Front Controller ์๋ํ (0) | 2020.02.20 |
Tomcat ์๋ฒ DataSource ์ค์ ๋ฐฉ๋ฒ (+JNDI) (1) | 2020.02.17 |
๋๊ธ