1. Seam Component 생성시의 인젝션순서 크게 2가지로 나누어 볼 수 있는데, ScopeType 을 지정하여 Component.getInstance 하는 경우와 그렇지 않은 경우이다. ScopeType을 지정하지 않으면 아래와 같다. [crayon] public static Object getInstance(String name, boolean create, boolean allowAutocreation) { Object result = Contexts.lookupInStatefulContexts(name); result = getInstance(name, create, allowAutocreation, result, null); return result; } [/crayon] Contexts.lookupInStatefulContexts의 스캔 순서는 2번에 정리. ScopeType이 있을 경우는 scopeType.getContext().get(name); 와 같이 각 Scope 별로 관리중인 Context 에서 인스턴스가 있는지 확인한다. 하지만 이때 인스턴스가 있다고 하여 그걸 그대로 리턴하는건 아니고 unwrap 을 한뒤에 리턴한다. unwrap에대해서는 3번에서 설명.

2. ScopeType 지정이 없을시의 검색순서

먼저 Contexts.lookupInStatefulContexts(name); 를 통해 아래 순서대로 검색한다.
method, event, page, conversation, session, business process, application.

3. @Unwrap

Component.getInstance 메소드를 보면 아래와 같이 되어 있다. [crayon] private static Object getInstance(String name, boolean create, boolean allowAutoCreation, Object result, ScopeType scope) { Component component = Component.forName(name); // 생략 result = component.unwrap(result); // 생략 return result; } [/crayon] 즉, 처음에 인스턴스가 없으면 만들고 이미 있다면 해당 인스턴스를 unwrap 한다. @Unwrap 메소드는 클래스내에서 단 1개의 메소드에만 지정할 수 있다. 물론 Unwrap메소드를 지정하지 않은 경우는 그냥 만들어진 인스턴스를 리턴한다. [crayon] public Object callComponentMethod(Object instance, Method method, Object… parameters) { Class[] paramTypes = method.getParameterTypes(); String methodName = method.getName(); try { Method interfaceMethod = instance.getClass().getMethod(methodName, paramTypes); if ( paramTypes.length==0 || interfaceMethod.getParameterTypes().length==0 ) { return Reflections.invokeAndWrap(interfaceMethod, instance); } else if ( parameters.length>0 ) { return Reflections.invokeAndWrap(interfaceMethod, instance, parameters); } else { return Reflections.invokeAndWrap(interfaceMethod, instance, this); } } catch (NoSuchMethodException e) { String message = “method not found: ” + method.getName() + ” for component: ” + name; if ( getType().isSessionBean() ) { message += ” (check that it is declared on the session bean business interface)”; } throw new IllegalArgumentException(message, e); } } [/crayon] 자.. 이걸보자. @Unwrap 이 붙은 메소드를 실행한 결과를 리턴한다. 즉, @In 또는 Component.getInstance 의 결과가 Context에 저장된 인스턴스를 리턴하는게 아니라 Unwrap이 지정한 메소드의 리턴값을 넘겨준다. 따라서 Unwrap을 지정한 메소드는 반드시 리턴값을 확인하여 @In 하거나 Component.getInstance로 클래스를 캐스트해야 한다. ]]>

Related Posts

답글 남기기

이메일 주소를 발행하지 않을 것입니다. 필수 항목은 *(으)로 표시합니다