1 4 package com.tcspring; 5 6 import org.apache.commons.logging.Log; 7 import org.apache.commons.logging.LogFactory; 8 import org.springframework.beans.factory.BeanFactory; 9 import org.springframework.context.ApplicationEvent; 10 import org.springframework.context.support.AbstractApplicationContext; 11 12 import com.tc.aspectwerkz.joinpoint.StaticJoinPoint; 13 import com.tc.object.bytecode.Manager; 14 import com.tc.object.bytecode.ManagerUtil; 15 import com.tc.object.config.DSOSpringConfigHelper; 16 17 import java.util.ArrayList ; 18 import java.util.Collection ; 19 import java.util.HashMap ; 20 import java.util.Iterator ; 21 import java.util.List ; 22 import java.util.Map ; 23 24 31 public class ApplicationContextEventProtocol { 32 33 private static transient Log logger = LogFactory.getLog(ApplicationContextEventProtocol.class); 34 35 39 private static transient final Map contexts = new HashMap (); 40 41 private transient ThreadLocal isInMulticastEventCflow; 42 43 private String appName; 44 private Collection configs; 45 private Collection beanNames; 46 private Collection eventTypes; 47 48 63 public void registerContext(StaticJoinPoint jp, AbstractApplicationContext ctx) { 64 DistributableBeanFactory distributableBeanFactory = (DistributableBeanFactory) ctx.getBeanFactory(); 65 if (!distributableBeanFactory.isClustered()) { return; } 66 67 String id = distributableBeanFactory.getId(); 68 List configHelpers = distributableBeanFactory.getSpringConfigHelpers(); 69 70 String lockName = "@spring_info_" + id; 71 72 ManagerUtil.beginLock(lockName, Manager.LOCK_TYPE_WRITE); 73 try { 74 populateAspectWithApplicationContextInfo(distributableBeanFactory, configHelpers); 75 List aspects = (List ) ManagerUtil.lookupOrCreateRoot("tc:spring_info:" + id, new ArrayList ()); 76 aspects.add(this); } finally { 78 ManagerUtil.commitLock(lockName); 79 } 80 81 synchronized (contexts) { 82 if (!contexts.containsKey(id)) { 83 contexts.put(id, ctx); 84 } 85 } 86 } 87 88 private void populateAspectWithApplicationContextInfo(DistributableBeanFactory distributableBeanFactory, List configHelpers) { 89 this.appName = distributableBeanFactory.getAppName(); 90 this.configs = distributableBeanFactory.getLocations(); 91 this.beanNames = new ArrayList (); 92 this.eventTypes = new ArrayList (); 93 94 for (Iterator it = configHelpers.iterator(); it.hasNext();) { 95 DSOSpringConfigHelper configHelper = (DSOSpringConfigHelper) it.next(); 96 this.beanNames.addAll(configHelper.getDistributedBeans().keySet()); 97 this.eventTypes.addAll(configHelper.getDistributedEvents()); 98 } 99 } 100 101 106 public Object interceptEvent(StaticJoinPoint jp, ApplicationEvent event, AbstractApplicationContext ctx) 107 throws Throwable { 108 109 BeanFactory beanFactory = ctx.getBeanFactory(); 110 if (tryToPublishDistributedEvent(beanFactory, event)) { 111 return null; 112 } 113 114 return jp.proceed(); 115 } 116 117 120 public boolean tryToPublishDistributedEvent(BeanFactory beanFactory, ApplicationEvent event) { 121 if (isInMulticastEventCflow != null && isInMulticastEventCflow.get() != null) { 122 return false; 124 } 125 126 if (ignoredEventType(event)) { 127 return false; 129 } 130 if (beanFactory instanceof DistributableBeanFactory) { 131 DistributableBeanFactory distributableBeanFactory = (DistributableBeanFactory) beanFactory; 132 if (distributableBeanFactory.isDistributedEvent(event.getClass().getName())) { 133 String ctxId = distributableBeanFactory.getId(); 134 boolean requireCommit = false; 136 try { 137 requireCommit = ManagerUtil.distributedMethodCall( 138 this, 139 "multicastEvent(Ljava/lang/String;Lorg/springframework/context/ApplicationEvent;)V", 140 new Object [] { ctxId, event }); 141 multicastEvent(ctxId, event); 143 } catch (Throwable e) { 144 logger.error("Unable to send event " + event + "; " + e.getMessage(), e); 145 } finally { 146 if(requireCommit) { 147 ManagerUtil.distributedMethodCallCommit(); 148 } 149 } 150 return true; 151 } 154 } 155 return false; 156 157 } 158 159 private boolean ignoredEventType(ApplicationEvent event) { 161 String name = event.getClass().getName(); 162 return "org.springframework.context.event.ContextRefreshedEvent".equals(name) 163 || "org.springframework.context.event.ContextClosedEvent".equals(name) 164 || "org.springframework.web.context.support.RequestHandledEvent".equals(name) 165 || "org.springframework.web.context.support.ServletRequestHandledEvent".equals(name); } 167 168 176 public void multicastEvent(final String ctxId, final ApplicationEvent event) { 177 AbstractApplicationContext context; 178 synchronized (contexts) { 179 context = (AbstractApplicationContext) contexts.get(ctxId); 180 } 181 182 logger.info(ctxId + " Publishing event " + event + " to " + context + " " + Thread.currentThread()); 183 184 if (context != null) { 185 publish(context, event); 186 } 187 } 188 189 private void publish(AbstractApplicationContext context, final ApplicationEvent event) { 190 if (isInMulticastEventCflow == null) { 191 isInMulticastEventCflow = new ThreadLocal (); 192 } 193 Integer n = (Integer ) isInMulticastEventCflow.get(); 194 if (n == null) { 195 isInMulticastEventCflow.set(new Integer (0)); 196 } else { 197 isInMulticastEventCflow.set(new Integer (n.intValue() + 1)); 198 } 199 try { 200 context.publishEvent(event); 201 } finally { 202 n = (Integer ) isInMulticastEventCflow.get(); 203 if (n == null || n.intValue() == 0) { 204 isInMulticastEventCflow.set(null); 205 } else { 206 isInMulticastEventCflow.set(new Integer (n.intValue() - 1)); 207 } 208 } 209 } 210 211 public String toString() { 212 return appName + ":" + configs; 213 } 214 } 215
| Popular Tags
|