/* * Copyright 2002-2015 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */
/** * Implementation of {@link AspectInstanceFactory} that is backed by a * specified singleton object, returning the same instance for every * {@link #getAspectInstance()} call. * * @author Rod Johnson * @author Juergen Hoeller * @since 2.0 * @see SimpleAspectInstanceFactory */ @SuppressWarnings("serial") publicclassSingletonAspectInstanceFactoryimplementsAspectInstanceFactory, Serializable {
privatefinal Object aspectInstance;
/** * Create a new SingletonAspectInstanceFactory for the given aspect instance. * @param aspectInstance the singleton aspect instance */ publicSingletonAspectInstanceFactory(Object aspectInstance) { Assert.notNull(aspectInstance, "Aspect instance must not be null"); this.aspectInstance = aspectInstance; }
@Override @Nullable public ClassLoader getAspectClassLoader() { returnthis.aspectInstance.getClass().getClassLoader(); }
/** * Determine the order for this factory's aspect instance, * either an instance-specific order expressed through implementing * the {@link org.springframework.core.Ordered} interface, * or a fallback order. * @see org.springframework.core.Ordered * @see #getOrderForAspectClass */ @Override publicintgetOrder() { if (this.aspectInstance instanceof Ordered) { return ((Ordered) this.aspectInstance).getOrder(); } return getOrderForAspectClass(this.aspectInstance.getClass()); }
/** * Determine a fallback order for the case that the aspect instance * does not express an instance-specific order through implementing * the {@link org.springframework.core.Ordered} interface. * <p>The default implementation simply returns {@code Ordered.LOWEST_PRECEDENCE}. * @param aspectClass the aspect class */ protectedintgetOrderForAspectClass(Class<?> aspectClass) { return Ordered.LOWEST_PRECEDENCE; }
@Override @Nullable public Object proceed()throws Throwable { // We start with an index of -1 and increment early. if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) { return invokeJoinpoint(); }
ObjectinterceptorOrInterceptionAdvice= this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex); if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) { // Evaluate dynamic method matcher here: static part will already have // been evaluated and found to match. InterceptorAndDynamicMethodMatcherdm= (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice; Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass()); if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) { return dm.interceptor.invoke(this); } else { // Dynamic matching failed. // Skip this interceptor and invoke the next in the chain. return proceed(); } } else { // It's an interceptor, so we just invoke it: The pointcut will have // been evaluated statically before this object was constructed. return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); } }
privatevoidreadObject(ObjectInputStream ois)throws IOException, ClassNotFoundException { // Rely on default serialization; just initialize state after deserialization. ois.defaultReadObject();
// This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. AdvisorAdapterRegistryregistry= GlobalAdvisorAdapterRegistry.getInstance(); Advisor[] advisors = config.getAdvisors(); List<Object> interceptorList = newArrayList<>(advisors.length); Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); BooleanhasIntroductions=null;
for (Advisor advisor : advisors) { if (advisor instanceof PointcutAdvisor) { // Add it conditionally. PointcutAdvisorpointcutAdvisor= (PointcutAdvisor) advisor; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { MethodMatchermm= pointcutAdvisor.getPointcut().getMethodMatcher(); boolean match; if (mm instanceof IntroductionAwareMethodMatcher) { if (hasIntroductions == null) { hasIntroductions = hasMatchingIntroductions(advisors, actualClass); } match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions); } else { match = mm.matches(method, actualClass); } if (match) { MethodInterceptor[] interceptors = registry.getInterceptors(advisor); if (mm.isRuntime()) { // Creating a new object instance in the getInterceptors() method // isn't a problem as we normally cache created chains. for (MethodInterceptor interceptor : interceptors) { interceptorList.add(newInterceptorAndDynamicMethodMatcher(interceptor, mm)); } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } elseif (advisor instanceof IntroductionAdvisor) { IntroductionAdvisoria= (IntroductionAdvisor) advisor; if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } } else { Interceptor[] interceptors = registry.getInterceptors(advisor); interceptorList.addAll(Arrays.asList(interceptors)); } }