package org.hotswap.agent.plugin.spring.getbean; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; import java.util.Arrays; import org.hotswap.agent.logging.AgentLogger; /** * Proxies the beans. The beans inside these proxies can be cleared. * * @author Erki Ehtla * */ public class ProxyReplacer { private static AgentLogger LOGGER = AgentLogger.getLogger(ProxyReplacer.class); private static Class<?> infrastructureProxyClass; /** * Name of the Spring beanFactory method, which returns a bean */ public static final String FACTORY_METHOD_NAME = "getBean"; /** * Clears the bean references inside all the proxies */ public static void clearAllProxies() { DetachableBeanHolder.detachBeans(); } /** * Creates a proxied Spring bean. Called from within WebApp code by modification of Spring classes * * @param beanFactry * Spring beanFactory * @param bean * Spring bean * @param paramClasses * Parameter Classes of the Spring beanFactory method which returned the bean. The method is named * ProxyReplacer.FACTORY_METHOD_NAME * @param paramValues * Parameter values of the Spring beanFactory method which returned the bean. The method is named * ProxyReplacer.FACTORY_METHOD_NAME * @return Proxied bean */ public static Object register(Object beanFactry, Object bean, Class<?>[] paramClasses, Object[] paramValues) { if (bean.getClass().getName().startsWith("com.sun.proxy.$Proxy")) { InvocationHandler handler = new HotswapSpringInvocationHandler(bean, beanFactry, paramClasses, paramValues); Class<?>[] interfaces = bean.getClass().getInterfaces(); try { if (!Arrays.asList(interfaces).contains(getInfrastructureProxyClass())) { interfaces = Arrays.copyOf(interfaces, interfaces.length + 1); interfaces[interfaces.length - 1] = getInfrastructureProxyClass(); } } catch (ClassNotFoundException e) { LOGGER.error("error adding org.springframework.core.InfrastructureProxy to proxy class", e); } return Proxy.newProxyInstance(beanFactry.getClass().getClassLoader(), interfaces, handler); } else if (EnhancerProxyCreater.isSupportedCglibProxy(bean)) { return EnhancerProxyCreater.createProxy(beanFactry, bean, paramClasses, paramValues); } return bean; } private static Class<?> getInfrastructureProxyClass() throws ClassNotFoundException { if (infrastructureProxyClass == null) { infrastructureProxyClass = ProxyReplacer.class.getClassLoader().loadClass("org.springframework.core.InfrastructureProxy"); } return infrastructureProxyClass; } }