书接上文,咱们说到AdvisedSupport类中的两个疑问点。
AdvisorChainFactory
//生产advosir链的工厂接口
public interface AdvisorChainFactory {
//用生advisor成一个MethodInterceptor的对象集合组(注意:这里仅仅是一个集合,是用来生成链的材料,并不是链)
List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, @Nullable Class<?> targetClass);
}
本工厂接口就一个方法,将Advised中的Advice根据Method生成对应的Interceptor集合,注解上所说的是MethodInterceptor并不准确。
为啥这么说呢?
1、既然使用泛型,既然是MethodInterceptor集合,何不直接使用MethodInterceptor作为泛型呢,所以这里可以看出来并不简单的同注解所说的一样。
可以看下AdvisorChainFactory的有且仅有的一个默认实现类DefaultAdvisorChainFactory是如何实现的。
DefaultAdvisorChainFactory
//一个简单的为方法生成一个advice链的工厂,并且不做缓存由子类或调用类做缓存
public class DefaultAdvisorChainFactory implements AdvisorChainFactory, Serializable {
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
Advised config, Method method, @Nullable Class<?> targetClass) {
//为了保证调用顺序需要做处理 introductions需要首先调用
//AdvisorAdapterRegistry这个工具就是将advisor转换成MethodInterceptor的
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();
List<Object> interceptorList = new ArrayList<>(advisors.length);
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
//通过遍历全部advisors将其进行类型转换为对应的interceptor
//如果是 PointcutAdvisor这种 转换为InterceptorAndDynamicMethodMatcher或MethodInterceptor
//如果是 IntroductionAdvisor 转换为IntroductionInterceptor
//如果是 Advisor 转换为MethodInterceptor
for (Advisor advisor : advisors) {
if (advisor instanceof PointcutAdvisor) {
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = 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(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;
}
... ...
}
内部主要生产三类interceptor,其实也就是对应了AOP概念中的三种代理类型,普通Advisor就是静态的直接转换成MethodInterceptor,在调用时也不需要判断,而PointcutAdvisor因为有内部有Pointcut所以需要判断isRuntiom方法是否为true因此这里为false则直接生成MethodInterceptor,为true需要判断方法参数,因此只能在运行时才知道所以生成了InterceptorAndDynamicMethodMatcher,而为类增加功能的代理introduction则直接生成IntroductionInteceptor因为这个接口就是MethodItercptor的子接口所以这里就直接添加进集合了。
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
在本类中又引出了一个接口AdvisorAdaptorRegistor,本接口就是将Advisor转换为MethodIterceptor。下面来看下本接口。
AdvisorAdaptorRegistor
// Advisor适配器注册表的接口。
//这是一个SPI接口,任何Spring使用者都不能实现。
public interface AdvisorAdapterRegistry {
// 对advice进行包装返回Advisor 。
// 默认情况下,至少应支持返回如下几种
// MethodInterceptor
// MethodBeforeAdvice
// AfterReturningAdvice
// ThrowsAdvice
Advisor wrap(Object advice) throws UnknownAdviceTypeException;
//返回一个AOP联盟的MethodInterceptor数组,允许在基于拦截的框架中使用给定的Advisor。
//如果它是org.springframework.aop.PointcutAdvisor ,则不必担心与Advisor关联的切入点:只需返回一个拦截器即可
MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException;
//注册给定的AdvisorAdapter。
//请注意,没有必要为AOP联盟的e拦截器或Spring咨询注册适配器:它们必须由AdvisorAdapterRegistry实现自动识别。
void registerAdvisorAdapter(AdvisorAdapter adapter);
}
- 接口方法将advice包装成Advisor
- 将Advisor转换为MethodInterceptor[],这里为啥是一个集合呢?因为这个advisor可能匹配多个MethodInterceptor,不过目前还没发现这种。
- 最重要的一个方法,注册AdvisorAdapter
这个AdvisorAdapter这里我想你应该也知道了,就是把Advisor转为MethodInterceptor
DefaultAdvisorAdapterRegistry
public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
private final List<AdvisorAdapter> adapters = new ArrayList<>(3);
public DefaultAdvisorAdapterRegistry() {
registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
registerAdvisorAdapter(new AfterReturningAdviceAdapter());
registerAdvisorAdapter(new ThrowsAdviceAdapter());
}
@Override
public 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) {
return new DefaultPointcutAdvisor(advice);
}
for (AdvisorAdapter adapter : this.adapters) {
if (adapter.supportsAdvice(advice)) {
return new DefaultPointcutAdvisor(advice);
}
}
throw new UnknownAdviceTypeException(advice);
}
@Override
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(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[0]);
}
@Override
public void registerAdvisorAdapter(AdvisorAdapter adapter) {
this.adapters.add(adapter);
}
}
方法清晰明了我想这里也就不需要在进行细致的讲解了。
那就看看AdvisorAdapter到底是哈?
AdvisorAdapter
public interface AdvisorAdapter {
boolean supportsAdvice(Advice advice);
MethodInterceptor getInterceptor(Advisor advisor);
}
- 判断这个adapter是否支持本advice
- 在就是转换操作了
本接口有很多实现类,但是内容都是大同小异的,就拿一个来瞅瞅
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
@Override
public boolean supportsAdvice(Advice advice) {
return (advice instanceof MethodBeforeAdvice);
}
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice();
return new MethodBeforeAdviceInterceptor(advice);
}
}
实现很简单,但是这里又引出了一个东西MethodBeforeAdviceInterceptor类就是MethodInterceptor的子类。那来看看这个子类都干啥了?
MethodBeforeAdviceInterceptor
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
return mi.proceed();
}
}
看invoke方法是不是有点熟悉呢?这是beforAdvice因此需要在方法调用前执行,在看invoke方法,是不是在proceed方法前调用的。
这里放出一个对应的类图。
AOP基础类图
本类图将上文所提及类根据功能生成一个依赖图。
上文在提及AopProxyFactory的时候只说了AdviseSupoort,并没有说AopProxyFactory如何生成AopProxy,也并没有说AopProxy是干嘛呢的。
接下来就是要细说下AopProxyFactory的独苗实现类,DefaultAopProxyFactory是如何实现的。
DefaultAopProxyFactory
//默认的AopProxyFactory实现类,创建CGLIB代理或JDK动态代理两者之一
//如果AdvisedSupport中条件满足则使用cglib创建代理
// optimize设置为true
// proxyTargetClass设置为true
// 没有指定代理接口,或者被代理的类没有实现接口
//通常proxyTargetClass参数会强制使用cglib代理,或者指定一个或多个接口则使用jdk动态代理
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
//确定提供的AdvisedSupport是否仅指定了SpringProxy接口
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
其实这里就是判断是使用什么方法生成代理对象
使用Cglib的三个依据
-
optimize设置为true
-
proxyTargetClass设置为true
-
没有指定代理接口,或者被代理的类没有实现接口
这里并没有什么复杂逻辑。
AopProxy
//用于配置的AOP代理的委托接口,允许创建实际的代理对象。
//如DefaultAopProxyFactory默认的实现可用于JDK动态代理和CGLIB代理
public interface AopProxy {
Object getProxy();
Object getProxy(@Nullable ClassLoader classLoader);
}
接口简单,生成代理类,获使用相应classLoader来加载class来生成类。
AopProxy有两个默认实现类,其一是JDKDynamicAopProxy,CglibAopProxy分别对应两种代理生成方式。
既然生成代理对象准备工作已经做完了,接下来就来看看如何生成代理对象的?