package springcommon; /** * Created by I311352 on 12/29/2016. */ import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.beans.factory.support.GenericBeanDefinition; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.context.annotation.Bean; import org.springframework.stereotype.Component; @Component public class ApplicationContextHolder implements ApplicationContextAware, BeanFactoryAware { private static ApplicationContext applicationContext; private static BeanFactory beanFactory; private static final ThreadLocal<HttpServletRequest> request = new ThreadLocal<>(); private static final ThreadLocal<HttpServletResponse> response = new ThreadLocal<>(); private static final Map<Integer, Set<HttpSession>> httpSessions = new ConcurrentHashMap<>(); private final static ReadWriteLock rwLock = new ReentrantReadWriteLock(); @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { ApplicationContextHolder.beanFactory = beanFactory; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { ApplicationContextHolder.applicationContext = applicationContext; } public static ApplicationContext getApplicationContext() { return applicationContext; } /** * @return the beanFactory */ public static BeanFactory getBeanFactory() { return beanFactory; } /** * @param clazz * @return */ public static <T> T getBean(Class<T> clazz) { if (clazz == null) { return null; } Lock rlock = rwLock.readLock(); rlock.lock(); try { return beanFactory == null ? null : beanFactory.getBean(clazz); } finally { rlock.unlock(); } } public static <T> Collection<T> getBeans(Class<T> clazz) { Map<String, T> beans = null; Lock rlock = rwLock.readLock(); rlock.lock(); try { beans = applicationContext.getBeansOfType(clazz); } finally { rlock.unlock(); } for (Iterator<Map.Entry<String, T>> iter = beans.entrySet().iterator(); iter.hasNext();) { Map.Entry<String, T> entry = iter.next(); if (entry.getKey().startsWith("scopedTarget")) { iter.remove(); } } return beans.values(); } public static <T> T getBean(String name, Class<T> clazz) { Lock rlock = rwLock.readLock(); rlock.lock(); try { return beanFactory.getBean(name, clazz); } finally { rlock.unlock(); } } @SuppressWarnings("unchecked") public static <T> T getBean(String name, Object... args) { Lock rlock = rwLock.readLock(); rlock.lock(); try { return (T) beanFactory.getBean(name, args); } finally { rlock.unlock(); } } /** * @param * @return */ public static Object getBean(String name) { Lock rlock = rwLock.readLock(); rlock.lock(); try { return beanFactory.getBean(name); } finally { rlock.unlock(); } } public static <T> void registerBeanDefinition(Class<T> clazz, String scope) { BeanDefinition definition = new GenericBeanDefinition(); definition.setScope(scope); definition.setBeanClassName(clazz.getName()); Lock wlock = rwLock.writeLock(); wlock.lock(); try { ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(clazz.getName(), definition); // TODO : Has to register beans twice to flush cache, might be a Spring defect. Workaround. ((DefaultListableBeanFactory) beanFactory).registerBeanDefinition(clazz.getName(), definition); } finally { wlock.unlock(); } } /** * @param request */ public static void setRequest(HttpServletRequest request) { ApplicationContextHolder.request.set(request); } /** * @param response */ public static void setResponse(HttpServletResponse response) { ApplicationContextHolder.response.set(response); } /** * @return */ public static HttpServletRequest getRequest() { return ApplicationContextHolder.request.get(); } /** * @return */ public static HttpServletResponse getResponse() { return ApplicationContextHolder.response.get(); } /** * @return */ public static HttpSession getSession() { return ApplicationContextHolder.request.get().getSession(); } /** * @return */ public static Map<Integer, Set<HttpSession>> getHttpsessions() { return httpSessions; } /** * @param tenantId * @param httpSession */ public static void addSession(Integer tenantId, HttpSession httpSession) { if (!httpSessions.containsKey(tenantId)) { httpSessions.put(tenantId, new HashSet<HttpSession>()); } httpSessions.get(tenantId).add(httpSession); } /** * @param tenantId * @param httpSession */ public static void removeSession(Integer tenantId, HttpSession httpSession) { if (httpSessions.containsKey(tenantId)) { httpSessions.get(tenantId).remove(httpSession); } } public static boolean containsBean(String name) { Lock rlock = rwLock.readLock(); rlock.lock(); try { return beanFactory.containsBean(name); } finally { rlock.unlock(); } } }