4、Advised
Advised: 已经被建议的对
// 这个 Advised 接口的实现着主要是代理生成的对象与AdvisedSupport (Advised的支持器) public interface Advised extends TargetClassAware { // 这个 frozen 决定是否 AdvisedSupport 里面配置的信息是否改变 boolean isFrozen(); // 是否代理指定的类, 而不是一些 Interface boolean isProxyTargetClass(); // 返回代理的接口 Class<?>[] getProxiedInterfaces(); // 判断这个接口是否是被代理的接口 boolean isInterfaceProxied(Class<?> intf); // 设置代理的目标对象 void setTargetSource(TargetSource targetSource); // 获取代理的对象 TargetSource getTargetSource(); // 判断是否需要将 代理的对象暴露到 ThreadLocal中, 而获取对应的代理对象则通过 AopContext 获取 void setExposeProxy(boolean exposeProxy); // 返回是否应该暴露 代理对象 boolean isExposeProxy(); // 设置 Advisor 是否已经在前面过滤过是否匹配 Pointcut (极少用到) void setPreFiltered(boolean preFiltered); // 获取 Advisor 是否已经在前面过滤过是否匹配 Pointcut (极少用到) boolean isPreFiltered(); // 获取所有的 Advisor Advisor[] getAdvisors(); // 增加 Advisor 到链表的最后 void addAdvisor(Advisor advisor) throws AopConfigException; // 在指定位置增加 Advisor void addAdvisor(int pos, Advisor advisor) throws AopConfigException; // 删除指定的 Advisor boolean removeAdvisor(Advisor advisor); // 删除指定位置的 Advisor void removeAdvisor(int index) throws AopConfigException; // 返回 Advisor 所在位置de index int indexOf(Advisor advisor); // 将指定的两个 Advisor 进行替换 boolean replaceAdvisor(Advisor a, Advisor b) throws AopConfigException; // 增加 Advice <- 这个Advice将会包裹成 DefaultPointcutAdvisor void addAdvice(Advice advice) throws AopConfigException; // 在指定 index 增加 Advice <- 这个Advice将会包裹成 DefaultPointcutAdvisor void addAdvice(int pos, Advice advice) throws AopConfigException; // 删除给定的 Advice boolean removeAdvice(Advice advice); // 获取 Advice 的索引位置 int indexOf(Advice advice); // 将 ProxyConfig 通过 String 形式返回 String toProxyConfigString(); }
它的主要实现,就是面向我们创建代理的,非常实用:
- ProxyFactory: 这个类通过构造函数中的 proxyInterface/interceptor/targetSource 来创建代理对象(这个类是编程式 AOP 中最常用的对象)
- ProxyFactoryBean: 这个类是基于 FactoryBean 的 Proxy创建形式, 其通过代理的 Interface, targetSource 与指定的 interceptorNames 来创建对应的AopProxy, 最后生成对应的代理对象
- AspectJProxyFactory: 将一个被 @Aspect 注解标示的类丢入其中, 变创建了对应的代理对象 (这个类现在已经很少用了。 但是@Aspect方式常用哦)
5、TargetSource
TargetSource:其实是动态代理作用的对象
- HotSwappableTargetSource: 进行线程安全的热切换到对另外一个对象实施动态代理操作
- AbstractPoolingTargetSource: 每次进行生成动态代理对象时都返回一个新的对象(比如内部实现类CommonsPool2TargetSource就是例子,但它依赖于common-pool2包)
- ThreadLocalTargetSource: 为每个进行请求的线程维护一个对象的 TargetSource
- SingletonTargetSource: 最普遍最基本的单例 TargetSource, 在 Spring 中生成动态代理对象, 一般都是用这个 TargetSource
6、AdvisorChainFactory
这个接口主要定义了从 Advised中获取 Advisor 并判断其是否与 对应的 Method 相匹配, 最终返回的是MethodInterceptor。(其中对 Advisor 转化成 MethodInterceptor 的工作都是交由 DefaultAdvisorAdapterRegistry 来完成, ) 它的实现类为:DefaultAdvisorChainFactory,提供的唯一方法是:
// 获取匹配 targetClass 与 method 的所有切面的通知 @Override public List<Object> getInterceptorsAndDynamicInterceptionAdvice( Advised config, Method method, Class<?> targetClass) { // This is somewhat tricky... We have to process introductions first, // but we need to preserve order in the ultimate list. List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length); // PS: 这里 config.getAdvisors 获取的是 advisors 是数组 Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); boolean hasIntroductions = hasMatchingIntroductions(config, actualClass); // 判断是有 IntroductionAdvisor 匹配到 // 下面这个适配器将通知 [Advice] 包装成拦截器 [MethodInterceptor]; 而 DefaultAdvisorAdapterRegistry则是适配器的默认实现 AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); for (Advisor advisor : config.getAdvisors()) { // 获取所有的 Advisor if (advisor instanceof PointcutAdvisor) { // advisor 是 PointcutAdvisor 的子类 // Add it conditionally. PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; // 判断此切面 [advisor] 是否匹配 targetClass (PS: 这里是类级别的匹配) if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { /** 通过对适配器将通知 [Advice] 包装成 MethodInterceptor, 这里为什么是个数组? 因为一个通知类 * 可能同时实现了前置通知[MethodBeforeAdvice], 后置通知[AfterReturingAdvice], 异常通知接口[ThrowsAdvice] * 环绕通知 [MethodInterceptor], 这里会将每个通知统一包装成 MethodInterceptor */ MethodInterceptor[] interceptors = registry.getInterceptors(advisor); MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); // 是否匹配 targetClass 类的 method 方法 (PS: 这里是方法级别的匹配) if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) { if (mm.isRuntime()) { // 看了对应的所有实现类, 只有 ControlFlowPointcut 与 AspectJExpressionPointcut 有可能 返回 true // 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)); // 里面装的是 Advise 与 MethodMatcher } } else { interceptorList.addAll(Arrays.asList(interceptors)); } } } } else if (advisor instanceof IntroductionAdvisor) { // 这里是 IntroductionAdvisor // 如果是引入切面的话则判断它是否适用于目标类, Spring 中默认的引入切面实现是 DefaultIntroductionAdvisor 类 // 默认的引入通知是 DelegatingIntroductionInterceptor 它实现了 MethodInterceptor 接口s 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; }