이전 응용 프로그램 중 하나에서 비슷한 필요성이있었습니다. 우리가 생각해 낸 해결책은 ResourceLoader (컨텍스트)에 의해 리소스 (Logger, Config 파일 등)를 검색하는 ResourceManager였습니다.
은 일반적으로 EAR로 배포 모든 응용 프로그램이 자체 클래스 로더를 얻고 라이브러리가 그럼 그냥 ResourceManager.getLogger를 호출 할 수 있습니다() 현재 스레드/응용 프로그램과 관련된 로거를 얻을 수 있습니다. 그렇게하면 라이브러리의 모든 메서드 호출에 전달할 필요가 없습니다 (라이브러리를 변경할 수 있어야합니다).
Logger logger = Logger.getLogger([Application Logger Name]);
ResourceManager.registerLogger(logger);
라이브러리에서 로거를 검색 (유틸리티 메소드) :
private Logger getLogger()
{
return ResourceManager.getLogger();
}
EJB/웹 애플리케이션의 초기화 단계에서
import java.util.*;
import java.util.logging.*;
public class ResourceManager
{
private static final Map<ClassLoader, Map<String, Object>> resources =
Collections.synchronizedMap(new WeakHashMap<ClassLoader, Map<String, Object>>());
public static final String LOGGER = Logger.class.getName();
static
{
// adjust for log4j or other frameworks
final Logger logger = Logger.getLogger("logging.default");
logger.setLevel(Level.ALL);
logger.addHandler(new ConsoleHandler()
{
{
setOutputStream(System.out);
setLevel(Level.ALL);
}
});
registerResource(null, LOGGER, logger);
}
private static ClassLoader getApplicationScope()
{
return Thread.currentThread().getContextClassLoader();
}
public static void registerResource(final String name, final Object resource)
{
registerResource(getApplicationScope(), name, resource);
}
public static synchronized void registerResource(final ClassLoader scope, final String name, final Object resource)
{
Map<String, Object> hm = null;
hm = resources.get(scope);
if (hm == null)
{
hm = Collections.synchronizedMap(new HashMap<String, Object>());
resources.put(scope, hm);
}
hm.put(name, resource);
}
public static Object getResource(final String name)
{
for(ClassLoader scope = getApplicationScope();;scope = scope.getParent())
{
final Map<String, Object> hm = resources.get(scope);
if ((hm != null) && hm.containsKey(name))
{
return hm.get(name);
}
if (scope == null) break;
}
return null;
}
public static void registerLogger(final Logger logger)
{
registerResource(LOGGER, logger);
}
public static Logger getLogger()
{
return (Logger)getResource(LOGGER);
}
}
등록 로거 (getLogger에 대한 호출하기 전에 등록해야합니다)
이것은 현재 스레드와 연관된 응용 프로그램 (EAR)에 대한 로거를 리턴합니다.
로거에 국한되지 않고 공유하려는 다른 리소스에도 사용할 수 있습니다.
제한 : 당신이 전개 된 EAR
는 ResourceManager 및 로깅 라이브러리에 여러 응용 프로그램/EJB를 패키징 할 경우
참고 자료로이 솔루션은 로거뿐만 아니라 모든 종류의 리소스를 공유하는 데 사용할 수도 있습니다. – Stefan
링크가 미래에 죽을 경우를 대비하여 관련 코드 섹션을 답안에 붙여 넣기를 원할 수 있습니다. – rouble
이 메서드에 대해주의 할 점은 라이브러리가 인스턴스화되기 전에 ResourceManager.registerLogger()를 호출해야한다는 것입니다. 그렇지 않으면 클래스 로거는 기본 로거를 사용하여 모두 설정됩니다. 이것은 일부 구현의 경우 거래 차단기가 될 수 있습니다. – rouble