java面试题网站:www.javaoffers.com
设计到的核心类:
CglibAopProxy 该类包含了大量的内部类(都属于各种代理类)
AbstractAutowireCapableBeanFactory:核心方法 doCreateBean源码
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args){
//创建实例对象,并封装在BeanWrapper 类中,
//底层利用jdk 反射,constructor.newInstance(args)
BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);
//开始注入bean实例中的属性,例如使用@Resource 注解的属性
populateBean(beanName, mbd, instanceWrapper);
//开始创建代理对象,并将实例bean封装到代理对象中,返回代理对象exposedObject
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
通过分析spring代理类的创建源码,可以把这些代理类拦截器 都统一理解为切面。并且这些切面在一集合中,这些切面的的执行是通过 链的设计模式去执行的。
核心类:ReflectiveMethodInvocation 的子类 CglibMethodInvocation
属性 :List<?> interceptorsAndDynamicMethodMatchers 封装切面,并用链的模式去执行
在spring框架中设计切面拦截(上面所说的代理类拦截器) 分两种:
静态的:spring自己支持声明的逻辑处理,比如事务拦截,是spring框架自己写的逻辑切面
动态的:是我们程序员自己利用spring提供的API 生成的,比如使用@Aspect 注解的切面,自己写逻辑切面
下面为核心代码:ReflectiveMethodInvocation 类中
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
//当最后一个chain执行完成后,就会走到我们自己切点上,比如我们自己 controller 中的方法。
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;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
//是我们程序员自己利用spring提供的API 生成的
return dm.interceptor.invoke(this);
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
//匹配失败时,跳入下一个chain,保证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.
//静态的,为spring框架自己声明支持的,比如事务切面等等
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}