1 16 17 package org.springframework.aop.aspectj.annotation; 18 19 import java.lang.reflect.Method ; 20 21 import org.aopalliance.aop.Advice; 22 import org.aspectj.lang.reflect.PerClauseKind; 23 24 import org.springframework.aop.Pointcut; 25 import org.springframework.aop.aspectj.AspectJExpressionPointcut; 26 import org.springframework.aop.aspectj.AspectJPrecedenceInformation; 27 import org.springframework.aop.aspectj.InstantiationModelAwarePointcutAdvisor; 28 import org.springframework.aop.aspectj.annotation.AbstractAspectJAdvisorFactory.AspectJAnnotation; 29 import org.springframework.aop.support.DynamicMethodMatcherPointcut; 30 import org.springframework.aop.support.Pointcuts; 31 32 40 class InstantiationModelAwarePointcutAdvisorImpl 41 implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation { 42 43 private final AspectJExpressionPointcut declaredPointcut; 44 45 private Pointcut pointcut; 46 47 private final MetadataAwareAspectInstanceFactory aspectInstanceFactory; 48 49 private final Method method; 50 51 private final boolean lazy; 52 53 private final AspectJAdvisorFactory atAspectJAdvisorFactory; 54 55 private Advice instantiatedAdvice; 56 57 private int declarationOrder; 58 59 private String aspectName; 60 61 private Boolean isBeforeAdvice = null; 62 63 private Boolean isAfterAdvice = null; 64 65 66 public InstantiationModelAwarePointcutAdvisorImpl( 67 AspectJAdvisorFactory af, 68 AspectJExpressionPointcut ajexp, 69 MetadataAwareAspectInstanceFactory aif, 70 Method method, 71 int declarationOrderInAspect, 72 String aspectName) { 73 74 this.declaredPointcut = ajexp; 75 this.method = method; 76 this.atAspectJAdvisorFactory = af; 77 this.aspectInstanceFactory = aif; 78 this.declarationOrder = declarationOrderInAspect; 79 this.aspectName = aspectName; 80 81 if (aif.getAspectMetadata().isLazilyInstantiated()) { 82 Pointcut preInstantiationPointcut = 84 Pointcuts.union(aif.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut); 85 86 this.pointcut = new PerTargetInstantiationModelPointcut(this.declaredPointcut, preInstantiationPointcut, aif); 90 this.lazy = true; 91 } 92 else { 93 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); 95 this.pointcut = declaredPointcut; 96 this.lazy = false; 97 } 98 } 99 100 101 105 public Pointcut getPointcut() { 106 return this.pointcut; 107 } 108 109 114 public boolean isPerInstance() { 115 return (getAspectMetadata().getAjType().getPerClause().getKind() != PerClauseKind.SINGLETON); 116 } 117 118 121 public AspectMetadata getAspectMetadata() { 122 return this.aspectInstanceFactory.getAspectMetadata(); 123 } 124 125 128 public synchronized Advice getAdvice() { 129 if (this.instantiatedAdvice == null) { 130 this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut); 131 } 132 return this.instantiatedAdvice; 133 } 134 135 public boolean isLazy() { 136 return this.lazy; 137 } 138 139 public synchronized boolean isAdviceInstantiated() { 140 return (this.instantiatedAdvice != null); 141 } 142 143 144 private Advice instantiateAdvice(AspectJExpressionPointcut pcut) { 145 return this.atAspectJAdvisorFactory.getAdvice( 146 this.method, pcut, this.aspectInstanceFactory, this.declarationOrder, this.aspectName); 147 } 148 149 public MetadataAwareAspectInstanceFactory getAspectInstanceFactory() { 150 return this.aspectInstanceFactory; 151 } 152 153 public AspectJExpressionPointcut getDeclaredPointcut() { 154 return this.declaredPointcut; 155 } 156 157 public int getOrder() { 158 return this.aspectInstanceFactory.getOrder(); 159 } 160 161 public String getAspectName() { 162 return this.aspectName; 163 } 164 165 public int getDeclarationOrder() { 166 return this.declarationOrder; 167 } 168 169 public boolean isBeforeAdvice() { 170 if (this.isBeforeAdvice == null) { 171 determineAdviceType(); 172 } 173 return this.isBeforeAdvice; 174 } 175 176 public boolean isAfterAdvice() { 177 if (this.isAfterAdvice == null) { 178 determineAdviceType(); 179 } 180 return this.isAfterAdvice; 181 } 182 183 187 private void determineAdviceType() { 188 AspectJAnnotation<?> aspectJAnnotation = 189 AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(this.method); 190 if (aspectJAnnotation == null) { 191 this.isBeforeAdvice = false; 192 this.isAfterAdvice = false; 193 } 194 else { 195 switch (aspectJAnnotation.getAnnotationType()) { 196 case AtAfter: 197 case AtAfterReturning: 198 case AtAfterThrowing: 199 this.isAfterAdvice = true; 200 this.isBeforeAdvice = false; 201 break; 202 case AtAround: 203 case AtPointcut: 204 this.isAfterAdvice = false; 205 this.isBeforeAdvice = false; 206 break; 207 case AtBefore: 208 this.isAfterAdvice = false; 209 this.isBeforeAdvice = true; 210 } 211 } 212 } 213 214 215 @Override 216 public String toString() { 217 return "InstantiationModelAwarePointcutAdvisor: expression [" + getDeclaredPointcut().getExpression() + 218 "]; advice method [" + this.method + "]; perClauseKind=" + 219 this.aspectInstanceFactory.getAspectMetadata().getAjType().getPerClause().getKind(); 220 221 } 222 223 224 229 private class PerTargetInstantiationModelPointcut extends DynamicMethodMatcherPointcut { 230 231 private final AspectJExpressionPointcut declaredPointcut; 232 233 private final Pointcut preInstantiationPointcut; 234 235 private LazySingletonAspectInstanceFactoryDecorator aspectInstanceFactory; 236 237 private PerTargetInstantiationModelPointcut(AspectJExpressionPointcut declaredPointcut, 238 Pointcut preInstantiationPointcut, MetadataAwareAspectInstanceFactory aspectInstanceFactory) { 239 this.declaredPointcut = declaredPointcut; 240 this.preInstantiationPointcut = preInstantiationPointcut; 241 if (aspectInstanceFactory instanceof LazySingletonAspectInstanceFactoryDecorator) { 242 this.aspectInstanceFactory = (LazySingletonAspectInstanceFactoryDecorator) aspectInstanceFactory; 243 } 244 } 245 246 @Override 247 public boolean matches(Method method, Class targetClass) { 248 return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)) || 250 this.preInstantiationPointcut.getMethodMatcher().matches(method, targetClass); 251 } 252 253 public boolean matches(Method method, Class targetClass, Object [] args) { 254 return (isAspectMaterialized() && this.declaredPointcut.matches(method, targetClass)); 256 } 257 258 private boolean isAspectMaterialized() { 259 return (this.aspectInstanceFactory == null || this.aspectInstanceFactory.isMaterialized()); 260 } 261 } 262 263 } 264 | Popular Tags |