import javax.servlet.ServletContext;

import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;

public class BeanFinder {
 
 private static ApplicationContext getApplicationContext( ServletContext context ) {
  return WebApplicationContextUtils.getWebApplicationContext( context );
 }
 
 public static Object getBean( ApplicationContext context, String id ) {
  return context.getBean( id );
 }
 public static Object getBean( ServletContext context, String id ) {
  return getBean( getApplicationContext( context ), id );
 }
 
 public static Object getBean( ApplicationContext context, Class clazz ) {
  return getBean( context, getBeanName( context, clazz ) );
 }
 
 public static Object getBean( ServletContext context, Class clazz ) {
  return getBean( getApplicationContext( context ), clazz );
 }
 
 public static String getBeanName( ApplicationContext context, Class clazz ) {
  
  for ( String beanName : context.getBeanNamesForType( clazz ) ) {
   // getBeanNamesForType은 지정 클래스의 하위 클래스들도 찾으므로,
   // 정확히 같은 클래스인지를 다시 검사해야 한다.
   if ( getBeanClassName( context, beanName ).equals( clazz.getName() ) ) return beanName;
  }
  
  return null;
 }
 
 private static String getBeanClassName( ApplicationContext context, String beanName ) {
  
  String className = context.getBean( beanName ).getClass().getName();
  int pos = className.indexOf( "$$" );
  
  // TODO Proxy 클래스일 경우는 원래 클래스 이름을 리턴해야 한다.
  return pos == -1 ? className : className.substring( 0, pos );
 }
}