1 16 17 package org.springframework.aop.framework; 18 19 import java.lang.reflect.Method ; 20 import java.util.ArrayList ; 21 import java.util.Iterator ; 22 import java.util.LinkedList ; 23 import java.util.List ; 24 import java.util.Map ; 25 26 import org.aopalliance.aop.Advice; 27 28 import org.springframework.aop.Advisor; 29 import org.springframework.aop.DynamicIntroductionAdvice; 30 import org.springframework.aop.IntroductionAdvisor; 31 import org.springframework.aop.IntroductionInfo; 32 import org.springframework.aop.TargetSource; 33 import org.springframework.aop.support.DefaultIntroductionAdvisor; 34 import org.springframework.aop.support.DefaultPointcutAdvisor; 35 import org.springframework.aop.target.EmptyTargetSource; 36 import org.springframework.aop.target.SingletonTargetSource; 37 import org.springframework.core.CollectionFactory; 38 import org.springframework.util.Assert; 39 import org.springframework.util.ClassUtils; 40 import org.springframework.util.ObjectUtils; 41 42 58 public class AdvisedSupport extends ProxyConfig implements Advised { 59 60 61 private static final long serialVersionUID = 2651364800145442165L; 62 63 64 68 public static final TargetSource EMPTY_TARGET_SOURCE = EmptyTargetSource.INSTANCE; 69 70 71 72 TargetSource targetSource = EMPTY_TARGET_SOURCE; 73 74 75 transient AdvisorChainFactory advisorChainFactory; 76 77 78 private transient Map methodCache; 79 80 84 private List interfaces = new ArrayList (); 85 86 90 private List advisors = new LinkedList (); 91 92 96 private Advisor[] advisorArray = new Advisor[0]; 97 98 99 102 public AdvisedSupport() { 103 initDefaultAdvisorChainFactory(); 104 } 105 106 110 public AdvisedSupport(Class [] interfaces) { 111 this(); 112 setInterfaces(interfaces); 113 } 114 115 118 private void initDefaultAdvisorChainFactory() { 119 setAdvisorChainFactory(new DefaultAdvisorChainFactory()); 120 this.methodCache = CollectionFactory.createIdentityMapIfPossible(32); 121 } 122 123 124 130 public void setTarget(Object target) { 131 setTargetSource(new SingletonTargetSource(target)); 132 } 133 134 public void setTargetSource(TargetSource targetSource) { 135 this.targetSource = (targetSource != null ? targetSource : EMPTY_TARGET_SOURCE); 136 } 137 138 public TargetSource getTargetSource() { 139 return this.targetSource; 140 } 141 142 155 public void setTargetClass(Class targetClass) { 156 this.targetSource = EmptyTargetSource.forClass(targetClass); 157 } 158 159 public Class getTargetClass() { 160 return this.targetSource.getTargetClass(); 161 } 162 163 167 public void setAdvisorChainFactory(AdvisorChainFactory advisorChainFactory) { 168 Assert.notNull(advisorChainFactory, "AdvisorChainFactory must not be null"); 169 this.advisorChainFactory = advisorChainFactory; 170 } 171 172 175 public AdvisorChainFactory getAdvisorChainFactory() { 176 return this.advisorChainFactory; 177 } 178 179 180 183 public void setInterfaces(Class [] interfaces) { 184 Assert.notNull(interfaces, "Interfaces must not be null"); 185 this.interfaces.clear(); 186 for (int i = 0; i < interfaces.length; i++) { 187 addInterface(interfaces[i]); 188 } 189 } 190 191 195 public void addInterface(Class intf) { 196 Assert.notNull(intf, "Interface must not be null"); 197 if (!intf.isInterface()) { 198 throw new IllegalArgumentException ("[" + intf.getName() + "] is not an interface"); 199 } 200 if (!this.interfaces.contains(intf)) { 201 this.interfaces.add(intf); 202 adviceChanged(); 203 } 204 } 205 206 213 public boolean removeInterface(Class intf) { 214 return this.interfaces.remove(intf); 215 } 216 217 public Class [] getProxiedInterfaces() { 218 return (Class []) this.interfaces.toArray(new Class [this.interfaces.size()]); 219 } 220 221 public boolean isInterfaceProxied(Class intf) { 222 for (Iterator it = this.interfaces.iterator(); it.hasNext();) { 223 Class proxyIntf = (Class ) it.next(); 224 if (intf.isAssignableFrom(proxyIntf)) { 225 return true; 226 } 227 } 228 return false; 229 } 230 231 232 public final Advisor[] getAdvisors() { 233 return this.advisorArray; 234 } 235 236 public void addAdvisor(Advisor advisor) { 237 int pos = this.advisors.size(); 238 addAdvisor(pos, advisor); 239 } 240 241 public void addAdvisor(int pos, Advisor advisor) throws AopConfigException { 242 if (advisor instanceof IntroductionAdvisor) { 243 validateIntroductionAdvisor((IntroductionAdvisor) advisor); 244 } 245 addAdvisorInternal(pos, advisor); 246 } 247 248 public boolean removeAdvisor(Advisor advisor) { 249 int index = indexOf(advisor); 250 if (index == -1) { 251 return false; 252 } 253 else { 254 removeAdvisor(index); 255 return true; 256 } 257 } 258 259 public void removeAdvisor(int index) throws AopConfigException { 260 if (isFrozen()) { 261 throw new AopConfigException("Cannot remove Advisor: Configuration is frozen."); 262 } 263 if (index < 0 || index > this.advisors.size() - 1) { 264 throw new AopConfigException("Advisor index " + index + " is out of bounds: " + 265 "This configuration only has " + this.advisors.size() + " advisors."); 266 } 267 268 Advisor advisor = (Advisor) this.advisors.get(index); 269 if (advisor instanceof IntroductionAdvisor) { 270 IntroductionAdvisor ia = (IntroductionAdvisor) advisor; 271 for (int j = 0; j < ia.getInterfaces().length; j++) { 273 removeInterface(ia.getInterfaces()[j]); 274 } 275 } 276 277 this.advisors.remove(index); 278 updateAdvisorArray(); 279 adviceChanged(); 280 } 281 282 public int indexOf(Advisor advisor) { 283 Assert.notNull(advisor, "Advisor must not be null"); 284 return this.advisors.indexOf(advisor); 285 } 286 287 public boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException { 288 Assert.notNull(a, "Advisor a must not be null"); 289 Assert.notNull(b, "Advisor b must not be null"); 290 int index = indexOf(a); 291 if (index == -1) { 292 return false; 293 } 294 removeAdvisor(index); 295 addAdvisor(index, b); 296 return true; 297 } 298 299 303 public void addAllAdvisors(Advisor[] advisors) { 304 if (isFrozen()) { 305 throw new AopConfigException("Cannot add advisor: Configuration is frozen."); 306 } 307 if (!ObjectUtils.isEmpty(advisors)) { 308 for (int i = 0; i < advisors.length; i++) { 309 Advisor advisor = advisors[i]; 310 if (advisor instanceof IntroductionAdvisor) { 311 validateIntroductionAdvisor((IntroductionAdvisor) advisor); 312 } 313 Assert.notNull(advisor, "Advisor must not be null"); 314 this.advisors.add(advisor); 315 } 316 updateAdvisorArray(); 317 adviceChanged(); 318 } 319 } 320 321 private void validateIntroductionAdvisor(IntroductionAdvisor advisor) { 322 advisor.validateInterfaces(); 323 Class [] ifcs = advisor.getInterfaces(); 325 for (int i = 0; i < ifcs.length; i++) { 326 addInterface(ifcs[i]); 327 } 328 } 329 330 private void addAdvisorInternal(int pos, Advisor advisor) throws AopConfigException { 331 Assert.notNull(advisor, "Advisor must not be null"); 332 if (isFrozen()) { 333 throw new AopConfigException("Cannot add advisor: Configuration is frozen."); 334 } 335 if (pos > this.advisors.size()) { 336 throw new IllegalArgumentException ( 337 "Illegal position " + pos + " in advisor list with size " + this.advisors.size()); 338 } 339 this.advisors.add(pos, advisor); 340 updateAdvisorArray(); 341 adviceChanged(); 342 } 343 344 347 protected final void updateAdvisorArray() { 348 this.advisorArray = (Advisor[]) this.advisors.toArray(new Advisor[this.advisors.size()]); 349 } 350 351 356 protected final List getAdvisorsInternal() { 357 return this.advisors; 358 } 359 360 361 public void addAdvice(Advice advice) throws AopConfigException { 362 int pos = this.advisors.size(); 363 addAdvice(pos, advice); 364 } 365 366 369 public void addAdvice(int pos, Advice advice) throws AopConfigException { 370 Assert.notNull(advice, "Advice must not be null"); 371 if (advice instanceof IntroductionInfo) { 372 addAdvisor(pos, new DefaultIntroductionAdvisor(advice, (IntroductionInfo) advice)); 375 } 376 else if (advice instanceof DynamicIntroductionAdvice) { 377 throw new AopConfigException("DynamicIntroductionAdvice may only be added as part of IntroductionAdvisor"); 379 } 380 else { 381 addAdvisor(pos, new DefaultPointcutAdvisor(advice)); 382 } 383 } 384 385 public boolean removeAdvice(Advice advice) throws AopConfigException { 386 int index = indexOf(advice); 387 if (index == -1) { 388 return false; 389 } 390 else { 391 removeAdvisor(index); 392 return true; 393 } 394 } 395 396 public int indexOf(Advice advice) { 397 Assert.notNull(advice, "Advice must not be null"); 398 for (int i = 0; i < this.advisors.size(); i++) { 399 Advisor advisor = (Advisor) this.advisors.get(i); 400 if (advisor.getAdvice() == advice) { 401 return i; 402 } 403 } 404 return -1; 405 } 406 407 412 public boolean adviceIncluded(Advice advice) { 413 Assert.notNull(advice, "Advice must not be null"); 414 for (int i = 0; i < this.advisors.size(); i++) { 415 Advisor advisor = (Advisor) this.advisors.get(i); 416 if (advisor.getAdvice() == advice) { 417 return true; 418 } 419 } 420 return false; 421 } 422 423 428 public int countAdvicesOfType(Class adviceClass) { 429 Assert.notNull(adviceClass, "Advice class must not be null"); 430 int count = 0; 431 for (int i = 0; i < this.advisors.size(); i++) { 432 Advisor advisor = (Advisor) this.advisors.get(i); 433 if (advisor.getAdvice() != null && 434 adviceClass.isAssignableFrom(advisor.getAdvice().getClass())) { 435 count++; 436 } 437 } 438 return count; 439 } 440 441 442 449 public List getInterceptorsAndDynamicInterceptionAdvice(Method method, Class targetClass) { 450 synchronized (this.methodCache) { 451 List cached = (List ) this.methodCache.get(method); 452 if (cached == null) { 453 cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( 454 this, null, method, targetClass); 455 this.methodCache.put(method, cached); 456 } 457 return cached; 458 } 459 } 460 461 464 protected void adviceChanged() { 465 synchronized (this.methodCache) { 466 this.methodCache.clear(); 467 } 468 } 469 470 475 protected void copyConfigurationFrom(AdvisedSupport other) { 476 copyConfigurationFrom(other, other.targetSource, new ArrayList (other.advisors)); 477 } 478 479 486 protected void copyConfigurationFrom(AdvisedSupport other, TargetSource targetSource, List advisors) { 487 copyFrom(other); 488 this.targetSource = targetSource; 489 this.advisorChainFactory = other.advisorChainFactory; 490 this.interfaces = new ArrayList (other.interfaces); 491 for (Iterator it = advisors.iterator(); it.hasNext();) { 492 Advisor advisor = (Advisor) it.next(); 493 if (advisor instanceof IntroductionAdvisor) { 494 validateIntroductionAdvisor((IntroductionAdvisor) advisor); 495 } 496 Assert.notNull(advisor, "Advisor must not be null"); 497 this.advisors.add(advisor); 498 } 499 updateAdvisorArray(); 500 adviceChanged(); 501 } 502 503 504 508 511 protected Object writeReplace() { 512 AdvisedSupport copy = this; 514 515 if (!getClass().equals(AdvisedSupport.class)) { 517 copy = new AdvisedSupport(); 518 copy.copyConfigurationFrom(this); 519 } 520 521 return copy; 523 } 524 525 528 private Object readResolve() { 529 initDefaultAdvisorChainFactory(); 530 return this; 531 } 532 533 534 public String toProxyConfigString() { 535 return toString(); 536 } 537 538 541 public String toString() { 542 StringBuffer sb = new StringBuffer (getClass().getName() + ": "); 543 sb.append(this.interfaces.size()).append(" interfaces "); 544 sb.append(ClassUtils.classNamesToString(this.interfaces)).append("; "); 545 sb.append(this.advisors.size()).append(" advisors "); 546 sb.append(this.advisors).append("; "); 547 sb.append("targetSource [").append(this.targetSource).append("]; "); 548 sb.append(super.toString()); 549 return sb.toString(); 550 } 551 552 } 553 | Popular Tags |