Spring 源码粘贴8

来源:互联网 发布:大数据项目调研内容 编辑:程序博客网 时间:2024/05/16 08:49

AOP拦截器

在动态代理这种实现方式的JdkDynamicAopProxy这个类中的invoke(),调用时最后一个参数是this因为它自身实现InvocationHandler接口

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {MethodInvocation invocation;TargetSource targetSource = this.advised.targetSource;Class<?> targetClass = null;Object target = null;...target = targetSource.getTarget();if (target != null) {targetClass = target.getClass();}List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);if (chain.isEmpty()) {Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);}else {// We need to create a method invocation...invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);// Proceed to the joinpoint through the interceptor chain.retVal = invocation.proceed();}// Massage return value if necessary.Class<?> returnType = method.getReturnType();if (retVal != null && retVal == target &&returnType != Object.class && returnType.isInstance(proxy) &&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {retVal = proxy;}...return retVal;}...}

在此方法内,获取了目标对象以及拦截器链并使用它们创建了ReflectiveMethodInvocation对象,并通过它来实现AOP功能

当没有拦截器时,直接调用目标方法

AopUtils.invokeJoinpointUsingReflection()

public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)throws Throwable {                ...ReflectionUtils.makeAccessible(method);return method.invoke(target, args);...}
对于拦截器链的调用,使用的proceed()

public Object proceed() throws Throwable {//We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}Object interceptorOrInterceptionAdvice =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.InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;if (dm.methodMatcher.matches(this.method, this.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);}}
这是一个被设计来递归的方法.从拦截器链中逐步获取拦截器,并调用拦截器的切入点match()来检测是否符合切入规则.是则获取通知器,并启动通知器的invoke()方法进行切面增强,否则继续proceed()下一个拦截器处理
我们来看拦截器从哪里来,上上一段代码中有

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {MethodCacheKey cacheKey = new MethodCacheKey(method);List<Object> cached = this.methodCache.get(cacheKey);if (cached == null) {cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(this, method, targetClass);this.methodCache.put(cacheKey, cached);}return cached;}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {//从配置文件中获取通知器的个数List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();for (Advisor advisor : config.getAdvisors()) {if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor);MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {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(new InterceptorAndDynamicMethodMatcher(interceptor, mm));}}else {interceptorList.addAll(Arrays.asList(interceptors));}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (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));}}return interceptorList;}
通过一个AdvisorAdapterRegister来实现拦截器的注册,通过它将配置文件中获取的通知进行适配得到对应的拦截器,然后添加到list去.
突然讲到这个config.getAdvisors()其实是从AdvisorSupport中获取的.而这个值又是在ProxyFactoryBean初始化的时候设置的.

private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {...if (this.singleton || this.beanFactory.isSingleton(name)) {// Add the real Advisor/Advice to the chain.advice = this.beanFactory.getBean(name);}else {// It's a prototype Advice or Advisor: replace with a prototype.// Avoid unnecessary creation of prototype bean just for advisor chain initialization.advice = new PrototypePlaceholderAdvisor(name);...}
通过this.beanFactory.getBean()来获取通知器
这里的beanFactory实在哪里获取的IoC容器呢.

在AbstractAutowireCapableBeanFactory中有一个initializeBean()

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {...invokeAwareMethods(beanName, bean);}
private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}}
如果这个bean实现了BeanFactoryAware接口就通过setBeanFactory()将IoC容器赋值到这个bean的beanFactory属性上.

Advice通知的实现

在拦截器获取的方法有这么一句

AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
然后通过这个registry获取拦截器

看GlobalAdvisorAdapterRegistry

public abstract class GlobalAdvisorAdapterRegistry {/** * Keep track of a single instance so we can return it to classes that request it. */private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();/** * Return the singleton {@link DefaultAdvisorAdapterRegistry} instance. */public static AdvisorAdapterRegistry getInstance() {return instance;}/** * Reset the singleton {@link DefaultAdvisorAdapterRegistry}, removing any * {@link AdvisorAdapterRegistry#registerAdvisorAdapter(AdvisorAdapter) registered} * adapters. */static void reset() {instance = new DefaultAdvisorAdapterRegistry();}}
看唯一实例

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {private final List<AdvisorAdapter> adapters = new ArrayList<AdvisorAdapter>(3);/** * Create a new DefaultAdvisorAdapterRegistry, registering well-known adapters. */public DefaultAdvisorAdapterRegistry() {registerAdvisorAdapter(new MethodBeforeAdviceAdapter());registerAdvisorAdapter(new AfterReturningAdviceAdapter());registerAdvisorAdapter(new ThrowsAdviceAdapter());}@Overridepublic Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {if (adviceObject instanceof Advisor) {return (Advisor) adviceObject;}if (!(adviceObject instanceof Advice)) {throw new UnknownAdviceTypeException(adviceObject);}Advice advice = (Advice) adviceObject;if (advice instanceof MethodInterceptor) {// So well-known it doesn't even need an adapter.return new DefaultPointcutAdvisor(advice);}for (AdvisorAdapter adapter : this.adapters) {// Check that it is supported.if (adapter.supportsAdvice(advice)) {return new DefaultPointcutAdvisor(advice);}}throw new UnknownAdviceTypeException(advice);}@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);Advice advice = advisor.getAdvice();if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) advice);}for (AdvisorAdapter adapter : this.adapters) {if (adapter.supportsAdvice(advice)) {interceptors.add(adapter.getInterceptor(advisor));}}if (interceptors.isEmpty()) {throw new UnknownAdviceTypeException(advisor.getAdvice());}return interceptors.toArray(new MethodInterceptor[interceptors.size()]);}@Overridepublic void registerAdvisorAdapter(AdvisorAdapter adapter) {this.adapters.add(adapter);}}
通过适配将为每个通知都加上一个拦截器.
其中的几种Adapter都是继承AdvisorAdapter实现都是类似的

class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {@Overridepublic boolean supportsAdvice(Advice advice) {return (advice instanceof MethodBeforeAdvice);}@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) {MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();return new MethodBeforeAdviceInterceptor(advice);}}
一个supportAdvice()判断是否是这种通知,然后getInterceptor()返回一个包含通知的拦截器
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {private MethodBeforeAdvice advice;/** * Create a new MethodBeforeAdviceInterceptor for the given advice. * @param advice the MethodBeforeAdvice to wrap */public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {Assert.notNull(advice, "Advice must not be null");this.advice = advice;}@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );return mi.proceed();}}
拦截器的invoke()方法首先对通知的before()调用,完成它的本身工作,然后调用proceed()