⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aspectjexpressionpointcut.java

📁 spring framework 2.5.4源代码
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
		// and there will never be matching subclass at runtime.
		if (shadowMatch.alwaysMatches()) {
			return true;
		}
		else if (shadowMatch.neverMatches()) {
			return false;
		}
		else {
		  // the maybe case
		  return (beanHasIntroductions || matchesIgnoringSubtypes(shadowMatch) || matchesTarget(shadowMatch, targetClass));
		}
	}

	public boolean matches(Method method, Class targetClass) {
		return matches(method, targetClass, false);
	}

	public boolean isRuntime() {
		checkReadyToMatch();
		return this.pointcutExpression.mayNeedDynamicTest();
	}

	public boolean matches(Method method, Class targetClass, Object[] args) {
		checkReadyToMatch();
		ShadowMatch shadowMatch = null;
		ShadowMatch originalShadowMatch = null;
		try {
			shadowMatch = getShadowMatch(AopUtils.getMostSpecificMethod(method, targetClass), method);
			originalShadowMatch = getShadowMatch(method, method);
		}
		catch (ReflectionWorld.ReflectionWorldException ex) {
			// Could neither introspect the target class nor the proxy class ->
			// let's simply consider this method as non-matching.
			return false;
		}

		// Bind Spring AOP proxy to AspectJ "this" and Spring AOP target to AspectJ target,
		// consistent with return of MethodInvocationProceedingJoinPoint
		ProxyMethodInvocation pmi = null;
		Object targetObject = null;
		Object thisObject = null;
		try {
			MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation();
			targetObject = mi.getThis();
			if (!(mi instanceof ProxyMethodInvocation)) {
				throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
			}
			pmi = (ProxyMethodInvocation) mi;
			thisObject = pmi.getProxy();
		}
		catch (IllegalStateException ex) {
			// No current invocation...
			// TODO: Should we really proceed here?
			logger.debug("Couldn't access current invocation - matching with limited context: " + ex);
		}

		JoinPointMatch joinPointMatch = shadowMatch.matchesJoinPoint(thisObject, targetObject, args);

		/*
		 * Do a final check to see if any this(TYPE) kind of residue match. For
		 * this purpose, we use the original method's (proxy method's) shadow to
		 * ensure that 'this' is correctly checked against. Without this check,
		 * we get incorrect match on this(TYPE) where TYPE matches the target
		 * type but not 'this' (as would be the case of JDK dynamic proxies).
		 * <p>See SPR-2979 for the original bug.
		 */
		if (pmi != null) {  // there is a current invocation
			RuntimeTestWalker originalMethodResidueTest = new RuntimeTestWalker(originalShadowMatch);
			if (!originalMethodResidueTest.testThisInstanceOfResidue(thisObject.getClass())) {
				return false;
			}
		}
		if (joinPointMatch.matches() && pmi != null) {
			bindParameters(pmi, joinPointMatch);
		}
		return joinPointMatch.matches();
	}


	protected String getCurrentProxiedBeanName() {
		return ProxyCreationContext.getCurrentProxiedBeanName();
	}


	/**
	 * A match test returned maybe - if there are any subtype sensitive variables
	 * involved in the test (this, target, at_this, at_target, at_annotation) then
	 * we say this is not a match as in Spring there will never be a different
	 * runtime subtype.
	 */
	private boolean matchesIgnoringSubtypes(ShadowMatch shadowMatch) {
		return !(new RuntimeTestWalker(shadowMatch).testsSubtypeSensitiveVars());
	}

	private boolean matchesTarget(ShadowMatch shadowMatch, Class targetClass) {
		return new RuntimeTestWalker(shadowMatch).testTargetInstanceOfResidue(targetClass);
	}

	private void bindParameters(ProxyMethodInvocation invocation, JoinPointMatch jpm) {
		// Note: Can't use JoinPointMatch.getClass().getName() as the key, since
		// Spring AOP does all the matching at a join point, and then all the invocations
		// under this scenario, if we just use JoinPointMatch as the key, then
		// 'last man wins' which is not what we want at all.
		// Using the expression is guaranteed to be safe, since 2 identical expressions
		// are guaranteed to bind in exactly the same way.
		invocation.setUserAttribute(getExpression(), jpm);
	}

	private ShadowMatch getShadowMatch(Method targetMethod, Method originalMethod) {
		synchronized (this.shadowMapCache) {
			ShadowMatch shadowMatch = (ShadowMatch) this.shadowMapCache.get(targetMethod);
			if (shadowMatch == null) {
				try {
					shadowMatch = this.pointcutExpression.matchesMethodExecution(targetMethod);
				}
				catch (ReflectionWorld.ReflectionWorldException ex) {
					// Failed to introspect target method, probably because it has been loaded
					// in a special ClassLoader. Let's try the original method instead...
					if (targetMethod == originalMethod) {
						throw ex;
					}
					shadowMatch = this.pointcutExpression.matchesMethodExecution(originalMethod);
				}
				this.shadowMapCache.put(targetMethod, shadowMatch);
			}
			return shadowMatch;
		}
	}


	public boolean equals(Object other) {
		if (this == other) {
			return true;
		}
		if (!(other instanceof AspectJExpressionPointcut)) {
			return false;
		}
		AspectJExpressionPointcut otherPc = (AspectJExpressionPointcut) other;
		return ObjectUtils.nullSafeEquals(this.getExpression(), otherPc.getExpression()) &&
				ObjectUtils.nullSafeEquals(this.pointcutDeclarationScope, otherPc.pointcutDeclarationScope) &&
				ObjectUtils.nullSafeEquals(this.pointcutParameterNames, otherPc.pointcutParameterNames) &&
				ObjectUtils.nullSafeEquals(this.pointcutParameterTypes, otherPc.pointcutParameterTypes);
	}

	public int hashCode() {
		int hashCode = ObjectUtils.nullSafeHashCode(this.getExpression());
		hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutDeclarationScope);
		hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterNames);
		hashCode = 31 * hashCode + ObjectUtils.nullSafeHashCode(this.pointcutParameterTypes);
		return hashCode;
	}

	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("AspectJExpressionPointcut: ");
		if (this.pointcutParameterNames != null && this.pointcutParameterTypes != null) {
			sb.append("(");
			for (int i = 0; i < this.pointcutParameterTypes.length; i++) {
				sb.append(this.pointcutParameterTypes[i].getName());
				sb.append(" ");
				sb.append(this.pointcutParameterNames[i]);
				if ((i+1) < this.pointcutParameterTypes.length) {
					sb.append(", ");
				}
			}
			sb.append(")");
		}
		sb.append(" ");
		if (getExpression() != null) {
			sb.append(getExpression());
		}
		else {
			sb.append("<pointcut expression not set>");
		}
		return sb.toString();
	}


	/**
	 * Handler for the Spring-specific <code>bean()</code> pointcut designator
	 * extension to AspectJ.
	 * <p>This handler must be added to each pointcut object that needs to
	 * handle the <code>bean()</code> PCD. Matching context is obtained
	 * automatically by examining a thread local variable and therefore a matching
	 * context need not be set on the pointcut.
	 */
	private class BeanNamePointcutDesignatorHandler implements PointcutDesignatorHandler {

		private static final String BEAN_DESIGNATOR_NAME = "bean";

		public String getDesignatorName() {
			return BEAN_DESIGNATOR_NAME;
		}

		public ContextBasedMatcher parse(String expression) {
			return new BeanNameContextMatcher(expression);
		}
	}


	/**
	 * Matcher class for the BeanNamePointcutDesignatorHandler.
	 * 
	 * Static and dynamic match tests for this matcher always return true, 
	 * since the matching decision is made at the proxy creation time.
	 */
	private class BeanNameContextMatcher implements ContextBasedMatcher {

		private final NamePattern expressionPattern;

		public BeanNameContextMatcher(String expression) {
			this.expressionPattern = new NamePattern(expression);
		}

		public boolean couldMatchJoinPointsInType(Class someClass) {
			return true;
		}

		public boolean couldMatchJoinPointsInType(Class someClass, MatchingContext context) {
			return contextMatch();
		}

		public boolean matchesDynamically(MatchingContext context) {
			return true;
		}

		public FuzzyBoolean matchesStatically(MatchingContext context) {
			return FuzzyBoolean.YES;
		}

		public boolean mayNeedDynamicTest() {
			return false;
		}

		private boolean contextMatch() {
			String advisedBeanName = getCurrentProxiedBeanName();
			if (advisedBeanName == null || BeanFactoryUtils.isGeneratedBeanName(advisedBeanName)) {
				return false;
			}
			if (this.expressionPattern.matches(advisedBeanName)) {
				return true;
			}
			if (beanFactory != null) {
				String[] aliases = beanFactory.getAliases(advisedBeanName);
				for (int i = 0; i < aliases.length; i++) {
					if (this.expressionPattern.matches(aliases[i])) {
						return true;
					}
				}
			}
			return false;
		}
	}

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -