【小家Spring】Spring AOP各个组件概述与总结【Pointcut、Advice、Advisor、Advised、TargetSource、AdvisorChainFactory...】(中)

简介: 【小家Spring】Spring AOP各个组件概述与总结【Pointcut、Advice、Advisor、Advised、TargetSource、AdvisorChainFactory...】(中)

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();
}


它的主要实现,就是面向我们创建代理的,非常实用:


  1. ProxyFactory: 这个类通过构造函数中的 proxyInterface/interceptor/targetSource 来创建代理对象(这个类是编程式 AOP 中最常用的对象)
  2. ProxyFactoryBean: 这个类是基于 FactoryBean 的 Proxy创建形式, 其通过代理的 Interface, targetSource 与指定的 interceptorNames 来创建对应的AopProxy, 最后生成对应的代理对象
  3. AspectJProxyFactory: 将一个被 @Aspect 注解标示的类丢入其中, 变创建了对应的代理对象 (这个类现在已经很少用了。 但是@Aspect方式常用哦)


5、TargetSource


TargetSource:其实是动态代理作用的对象


  1. HotSwappableTargetSource: 进行线程安全的热切换到对另外一个对象实施动态代理操作
  2. AbstractPoolingTargetSource: 每次进行生成动态代理对象时都返回一个新的对象(比如内部实现类CommonsPool2TargetSource就是例子,但它依赖于common-pool2包)
  3. ThreadLocalTargetSource: 为每个进行请求的线程维护一个对象的 TargetSource
  4. 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;
}
相关文章
|
10天前
|
XML Java 数据安全/隐私保护
Spring Aop该如何使用
本文介绍了AOP(面向切面编程)的基本概念和术语,并通过具体业务场景演示了如何在Spring框架中使用Spring AOP。文章详细解释了切面、连接点、通知、切点等关键术语,并提供了完整的示例代码,帮助读者轻松理解和应用Spring AOP。
Spring Aop该如何使用
|
30天前
|
存储 缓存 Java
Spring高手之路23——AOP触发机制与代理逻辑的执行
本篇文章深入解析了Spring AOP代理的触发机制和执行流程,从源码角度详细讲解了Bean如何被AOP代理,包括代理对象的创建、配置与执行逻辑,帮助读者全面掌握Spring AOP的核心技术。
37 3
Spring高手之路23——AOP触发机制与代理逻辑的执行
|
10天前
|
负载均衡 算法 Java
除了 Ribbon,Spring Cloud 中还有哪些负载均衡组件?
这些负载均衡组件各有特点,在不同的场景和需求下,可以根据项目的具体情况选择合适的负载均衡组件来实现高效、稳定的服务调用。
27 5
|
15天前
|
Java Spring
[Spring]aop的配置与使用
本文介绍了AOP(面向切面编程)的基本概念和核心思想。AOP是Spring框架的核心功能之一,通过动态代理在不修改原代码的情况下注入新功能。文章详细解释了连接点、切入点、通知、切面等关键概念,并列举了前置通知、后置通知、最终通知、异常通知和环绕通知五种通知类型。
27 1
|
11天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
24 0
|
1月前
|
Java 数据库连接 数据库
让星星⭐月亮告诉你,SSH框架01、Spring概述
Spring是一个轻量级的Java开发框架,旨在简化企业级应用开发。它通过IoC(控制反转)和DI(依赖注入)降低组件间的耦合度,支持AOP(面向切面编程),简化事务管理和数据库操作,并能与多种第三方框架无缝集成,提供灵活的Web层支持,是开发高性能应用的理想选择。
36 1
|
2月前
|
设计模式 Java 测试技术
spring复习04,静态代理动态代理,AOP
这篇文章讲解了Java代理模式的相关知识,包括静态代理和动态代理(JDK动态代理和CGLIB),以及AOP(面向切面编程)的概念和在Spring框架中的应用。文章还提供了详细的示例代码,演示了如何使用Spring AOP进行方法增强和代理对象的创建。
spring复习04,静态代理动态代理,AOP
|
1月前
|
Java 编译器 Spring
Spring AOP 和 AspectJ 的区别
Spring AOP和AspectJ AOP都是面向切面编程(AOP)的实现,但它们在实现方式、灵活性、依赖性、性能和使用场景等方面存在显著区别。‌
68 2
|
1月前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
【10月更文挑战第1天】Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
127 9
|
2月前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
49 10