2022.01.12 TIL

서승원·2022년 1월 12일
0

TIL

목록 보기
52/68

Annotation을 이용한 방법

계속해서 다른 방식으로 만들고 있는 게시판 만들기를 Annotation을 이용한 각 함수 호출 방식으로 만들어봤다.

1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
    public String value();
}
 
cs
가장 먼저 각 함수를 구별하는 기준이 될 Annotatio인 RequestMapping Interface다. value() 를 이용해서 각 함수의 key,value를 연결시키도록 한다.
1
2
3
4
@Retention(RetentionPolicy.RUNTIME)
public @interface Control {
 
}
cs
Control interface 와 같이 사용할 인터페이스로, 마찬가지로 어노테이션을 이용해서 만들었다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Control
public class CtrlBang {
 
        @RequestMapping("/list.do2")
        public ModelAndView list( HttpServletRequest request, HttpServletResponse response) throws Exception 
        {
            System.out.println("list");
            return null;
        }
        
        @RequestMapping("/add2.do2")
        public ModelAndView add2( HttpServletRequest request, HttpServletResponse response) throws Exception 
        {
            System.out.println("add2");
            return null;
        }
        
        @RequestMapping("/down.do2")
        public ModelAndView down( HttpServletRequest request, HttpServletResponse response) throws Exception 
        {
            System.out.println("down");
            return null;
        }
}
cs
CtrlBang이다. 게시판을 만들기 위한 함수들을 이 파일에 모아둘 것이다. Control Interface를 상속받는 것 대신 @Control Annotation을 붙이는 것으로 단순 Controller에 해당하는 함수라고 구분한다. 우선 본격적으로 함수의 내용을 작성 전에 RequestMapping 어노테이션과 value() 를 통해 적절하게 연결돼서 호출되는 것을 확인하기 위해 함수 이름을 출력하기만 하도록 하고, 각각에 맞는 이름을 Annotation을 이용해서 붙였다.
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
public class Test525 extends HttpServlet{
 
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        System.out.printlnthis );
        String uri = request.getRequestURI();
        String ctxPath = request.getContextPath();
        
        String uri2 = uri.substring( ctxPath.length() );
        System.out.println( uri2 );
        
        Map<String,Method> methodMap = new Hashtable<String,Method>();
        
        Object obj = new CtrlBang();
        try {
            Class<?> cls = Class.forName("orange.CtrlBang");
            
            
            Control annot = cls.getAnnotation( Control.class );
            System.out.println( annot );
            if( annot != null )
            {
                Method[] mtds = cls.getMethods();
                for( Method mtd : mtds ) {
                    RequestMapping annot2 = mtd.getAnnotation( RequestMapping.class );
                    if( annot2 != null ) {
                        System.out.println( mtd );
                        System.out.println( annot2.value() );
                        
                        methodMap.put( annot2.value(), mtd );
                    }
                }
            }
        }
        catch( Exception e ) {}
        Method mtd2 = methodMap.get( uri2 );
        if( mtd2 != null ) {
            try {
                ModelAndView mnv = (ModelAndView) mtd2.invoke( obj, request, response );
            } catch (Exception e) {
                e.printStackTrace();
            }         
        }
    }
}
cs
CtrlBang과 페이지를 나타내줄 jsp 파일을 연결할 Test525.java 파일이다. 우선 접속한 URL로부터 호출되는 함수를 구분하기위해 uri2를 substring을 이용해 선언한다. methodMap 이라는 Hashtable의 생성은 key가 될 함수 별 이름과 해당 함수에 대한 포인터를 담고 있다. uri2가 가리키는 함수를 포인터와 연결해주는 역할을 한다. 그리고 CtrlBang의 인스턴스인 obj를 선언하고, cls에 그에 해당하는 함수들의 배열을, annot2에 그에 해당하는 함수에 대한 포인터를 Method 배열인 mtds에 대한 for문을 사용해서methodMap에 put 한다. 그리고 36 줄 부터 함수를 호출한다. Method2에 uri2(annot2.value()와 연결) 에 해당하는 함수를 get을 통해 대입하고, mtd2에 해당하는 함수(class)가 있다면, ModelAndView mnv에 mtd2를 invoke한다. 여기서 invoke의 매개변수는 , 해당 함수를 가진 인스턴스, 해당 함수의 매개변수이다.

이렇게해서 Annotation과 연결된 함수를 호출하기 위한 Test525.java 파일을 구성했다. 어노테이션을 활용해서 이런 프로그래밍을 하면, 해당 어노테이션에 대한 전체적인 관리가 쉬워진다. 이용하는 class들을 목적에 따라 구분해서 한 class에 모아둘 수 있고, 일괄적인 조작이 가능해진다.

어제 만든 방식에 비해서 달라진 점은 우선 파일의 수가 확 줄어들게 된다. CtrlBang에 모든 class들이 모여졌고, web.xml 파일에 대한 업데이트가 필요없어지고, 다른 기능을 추가할 때 직접 web.xml/java파일의 호출부분을 손 댈 필요가 없어진다.

profile
2년차 백엔드 개발자, crimy

0개의 댓글