精华内容
下载资源
问答
  • https://pan.baidu.com/disk/main#/transfer/send?surl=ABUAAAAAAAjABw
    展开全文
  • 小马哥 Spring编程思想笔记 文章目录 小马哥 Spring编程思想笔记 Spring Framework 课前准备 Spring 特性总览 Spring 版本特性 Spring 模块化设计 Spring 对Java语言特性运用 Spring 对JDK API 实践 Spring 对 Java...

    小马哥 Spring编程思想笔记

    文章目录
    小马哥 Spring编程思想笔记
    Spring Framework

    1. 课前准备
    2. Spring 特性总览
    3. Spring 版本特性
    4. Spring 模块化设计
    5. Spring 对Java语言特性运用
    6. Spring 对JDK API 实践
    7. Spring 对 Java EE API 整合
    8. Spring 编程模型
    9. Spring 核心价值
    10. 面试题精选
    11. 重新认识IoC
      AOP
      OOP与AOP区别
      底层实现原理

    小马哥笔记

    展开全文
  • 小马哥spring

    2020-12-27 08:59:23
    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。

    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。
    ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类对某一接口实现类的依赖由第三方(容器或者协作类)注入,从而移除调用类对某一接口实现类的依赖。注入方式可以划分为三种类型:构造函数注入、属性注入和接口注入。接口注入方式需要额外声明一个接口,增加了类的数目,并且其效果同属性注入并无区别,所以不提倡采用接口注入的方法。Spring是这样的一个容器,通过配置文件或注解描述类和类之间的依赖关系,自动完成类的初始化和依赖注入工作。Java允许用户借用Class相关的元信息对象间接调用Class的属性,构造器和方法,就是所谓的反射。invoke(Object object, Object param)第一个参数是操作目标类实例,第二个对象是目标方法的入参。Class没有public 的构造方法。Class对象是在装载类时由JVM通过调用类装载器中的defineClass()方法自动创造的。Java反射在java.reflect包中定义了三个最主要的反射类:Constructor:类的构造器反射类,通过Class#getConstructor()方法可以获得类的所有构造函数反射对象数组。通过该类的newInstance(Object[] initargs)可以创建一个对象的实例,相当于new,JDK 5.0之后演化成了newInstance(Object…initargs),使用起来更加方便。Method:类方法的反射类,通过Class#getDeclaredMethods()方法可以获得类的所有方法反射类的数组Method[]。该类的invoker(Object obj, Object[] args)可以调用这个方法,obj是目标对象,args是入参。Field:类的成员变量的反射类,通过Class#getDeclaredFields()方法可以获取类的成员变量的反射对象数组。Java的反射体系保证了可以通过程序化的方式访问目标类中的所有元素。private和protected的成员变量和方法在JVM安全机制允许的情况下也可以通过反射进行调用。JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。

    展开全文
  • 跟着小马哥学系列之 Spring AOP(ProxyProcessorSupport 详解)简介AbstractAutoProxyCreator 功能 学成路更宽,吊打面试官。 ——小马哥 简介 大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼...

    学成路更宽,吊打面试官。 ——小马哥

    版本修订

    • 2021.5.19:去除目录

    简介

    大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring AOP 编程思想》基础上形成的个人一些总结。希望能帮助各位小伙伴, 祝小伙伴早日学有所成。

    AbstractAutoProxyCreator 功能

    从命名可知这个抽象类主要功能就是自动创建代理,怎么实现自动?这就得与 Spring IoC 容器打通。所以此抽象类实现了 SmartInstantiationAwareBeanPostProcessorBeanFactoryAware

    • 使用 AOP 代理包装每个合格 bean 用 BeanPostProcessor 实现,在调用 bean 本身之前将委托给指定的拦截器。
    • 这个类区分了公共的拦截器(为它创建的所有代理共享)以及 特定的拦截器(每个 bean 实例都是唯一的)。如果有公共的拦截器,则使用 interceptorNames 属性设置它们(与 ProxyFactoryBean 一样,使用当前工厂中的拦截器名称而不是 bean 引用来允许正确处理原型 advisor 和拦截器)
    • 如果有大量 bean 需要用类似的代理进行包装,即委托给相同的拦截器,那么这种自动代理特别有用。您可以向 bean 工厂注册一个这样的后处理程序来实现相同的效果,而不是为 x 个目标 bean 重复定义 x 个代理。
    • 子类可以应用任何策略(子类可以实现 getAdvicesAndAdvisorsForBean 方法)来决定一个 bean 是否要被代理,例如根据类型、名称、定义细节等。它们还可以返回应该只应用于特定 bean 实例的额外拦截器。一个简单的具体实现是 BeanNameAutoProxyCreator,它通过给定的名称标识要代理的 bean。
    • 任意的 TargetSourceCreator 实现都可以用于创建自定义目标源:例如,将原型对象池化。即使没有 advice,只要 TargetSourceCreator 指定了自定义 TargetSource,也会发生自动代理。如果没有设置 TargetSourceCreators ,或者没有匹配的,默认情况下将使用 SingletonTargetSource 来包装目标 bean 实例。

    AbstractAutoProxyCreator 类图

    在这里插入图片描述

    相关类介绍

    AopInfrastructureBean

    标记接口,用于识别 Spring AOP 基础结构一部分的 bean,避免当 Pointcut 匹配时生成代理对象。

    ProxyConfig

    用于创建代理时配置的便利超类,以确保所有代理创建器具有一致的属性。

    主要配置:

    1. proxyTargetClass:同 @EnableAspectJAutoProxy 中的属性 proxyTargetClass 一样语义,是否使用 CGLIB 代理,默认是 false 使用 JDK 基于接口的动态代理
    2. optimize:设置代理是否应该执行主动优化。主动优化的确切含义在不同的代理之间是不同的,但通常会有一些权衡。默认设置是 false。例如,优化通常意味着在创建代理之后通知更改不会生效。因此,优化在默认情况下是禁用的。如果其他设置排除了优化,那么“true”的优化值可能会被忽略;例如,如果 exposeProxy 被设置为 true,而这与优化不兼容。
    3. opaque:默认值是 false,任何 AOP 代理都可以强制转换为 Advised
    4. exposeProxy:同 @EnableAspectJAutoProxy 中的属性 exposeProxy 一样语义,是否将代理对象暴露在 AopContext 类中。
    5. frozen:设置该配置是否应该被冻结。当一个配置被冻结时,不能做出任何 Advice 更改。这对于优化很有用,当我们不希望调用方能够在强制转换为 Adviced 后操作配置时也很有用。

    ProxyProcessorSupport

    具有代理处理器通用功能的基类,特别是 ClassLoader 管理和 evaluateProxyInterfaces 算法。

    管理 ClassLoader

    通过属性 boolean classLoaderConfigured 管理属性 proxyClassLoader 只允许设置一次

    evaluateProxyInterfaces() 方法解读

    检查给定 bean 类上的接口,并将它们应用到 ProxyFactory(如果可用的话)。调用 isConfigurationCallbackInterface(Class<?>) 和 sInternalLanguageInterface(Class<?>) 来过滤合理的代理接口。如果没有可用接口则使用 CGLIB 代理。

    protected void evaluateProxyInterfaces(Class<?> beanClass, ProxyFactory proxyFactory) {
    	// 获取类中的所有接口,如果是接口返回它自己
    	Class<?>[] targetInterfaces = ClassUtils.getAllInterfacesForClass(beanClass, getProxyClassLoader());
    	boolean hasReasonableProxyInterface = false;
    	/**
    	 *  获取的接口列表,只要接口列表满足一个不是 Spring 框架 InitializingBean、DisposableBean、Aware 接口扩展接口和
    	 *  不是 Jdk 中 AutoCloseable 和 Closeable 接口并且不是内部语言接口(接口名称是 groovy.lang.GroovyObject
    	 *  或者是以 .cglib.proxy.Factory 结尾或者 .bytebuddy.MockAccess 结尾)并且不是空接口
    	 */
    	for (Class<?> ifc : targetInterfaces) {
    		if (!isConfigurationCallbackInterface(ifc) && !isInternalLanguageInterface(ifc) &&
    				ifc.getMethods().length > 0) {
    			hasReasonableProxyInterface = true;
    			break;
    		}
    	}
    	// 如果有可代理的接口添加到代理工厂中
    	if (hasReasonableProxyInterface) {
    		for (Class<?> ifc : targetInterfaces) {
    			proxyFactory.addInterface(ifc);
    		}
    	}
    	else {
    		// 没有接口就设置 CGLIB 代理
    		proxyFactory.setProxyTargetClass(true);
    	}
    }
    

    BeanFactoryAware

    实现 setBeanFactory((BeanFactory beanFactory) 方法。并且该实现类交由 Spring IoC 管理。则由 Spring IoC 容器在填充普通 bean 属性之后,但在初始化回调(如 iinitializingBean.afterPropertiesSet() 或自定义初始化方法之前调用。

    BeanPostProcessor

    Bean 的后置处理器,可以通过实现此接口覆写 postProcessBeforeInitialization 和 postProcessAfterInitialization 方法对 bean 进行修改,比如 AbstractAutoProxyCreato 就是通过覆写 postProcessAfterInitialization 返回代理对象

    InstantiationAwareBeanPostProcessor

    BeanPostProcessor 的子接口,它添加了一个实例化之前的回调函数和一个实例化之后但在显式属性设置或自动装配发生之前的回调函数。通常用于抑制特定目标 bean 的默认实例化,例如创建带有特殊 targetsource 的代理(池化目标、延迟初始化目标等),或者实现额外的注入策略,如字段注入。

    SmartInstantiationAwareBeanPostProcessor

    此接口扩展了 InstantiationAwareBeanPostProcessor接口,添加一个 predictBeanType 回调,用于预测已处理 bean 的最终类型。

    AopProxy

    通过委派已配置的 Aop 代理接口,创建实际的代理对象。Spring AOP 通过 DefaultAopProxyFactory 提供了开箱即用 的 JDK 动态代理(JdkDynamicAopProxy) 和 CGLIB 代理(ObjenesisCglibAopProxy)

    • 通过 getProxy方法获取代理对象(默认的 ClassLoader)
    • 通过指定 ClassLoadergetProxy(@Nullable ClassLoader classLoader) 方法获取代理对象

    AopProxyFactory

    基于 AdvisedSupport 配置对象新增 AOP 代理的工厂接口

    代理应该遵守以下契约:

    • 应该实现配置的所有接口
    • 实现 Advised 接口
    • 实现 equals 方法用于比较代理接口、advice 和 目标对象
    • 如果所有的 advisor 和 目标对象都是可序列化的,代理对象应该也是可序列化的
    • 如果 advisor 和目标对象是线程安全的则代理对象也应该是线程安全的

    唯一实现:DefaultAopProxyFactory#createAopProxy(AdvisedSupport config) 方法分析

    AopProxyFactory 默认实现,创建不是 JDK 动态代理就是 CGLIB 代理。

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    	/**
    	 * 对于给定的 AdvisedSupport 实例,如果满足以下任意条件,则创建一个 CGLIB 代理:
    	 * 1. 优化标志被设置
    	 * 2. proxyTargetClass 标志被设置(即使设置了如果被代理对象是接口还是使用 JDK 动态代理)
    	 * 3. 没有指定代理接口
    	 */ 
    	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.");
    		}
    		// 目标对象是接口或者是已经被 JDK 动态代理代理过的对象则创建 JDK 动态代理
    		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    			return new JdkDynamicAopProxy(config);
    		}
    		return new ObjenesisCglibAopProxy(config);
    	}
    	else {
    		return new JdkDynamicAopProxy(config);
    	}
    }
    

    AbstractAutoProxyCreator 简介

    AdvisorAdapterRegistry 管理

    • 通过 advisorAdapterRegistry 属性管理 AdvisorAdapterRegistry 默认是 GlobalAdvisorAdapterRegistry(DefaultAdvisorAdapterRegistry),
    • 可以通过 setAdvisorAdapterRegistry() 方法进行设置

    TargetSourceCreator 使用

    在前面 AbstractAutoProxyCreator 功能介绍最后一条中介绍即使没有 Advice,只要 TargetSourceCreator 指定了自定义 TargetSource,也会发生自动代理,将会在 postProcessBeforeInstantiation 介绍

    • 可以通过 setCustomTargetSourceCreators(TargetSourceCreator… targetSourceCreators) 方法设置

    公共拦截器管理

    • 通过 interceptorNames 属性管理公共拦截器
    • 通过 setInterceptorNames(String... interceptorNames)方法进行设置
    • 通过 setApplyCommonInterceptorsFirst(boolean applyCommonInterceptorsFirst) 方法设置公共拦截器与特殊拦截的先后顺序

    BeanFactory 管理

    由于 AbstractAutoProxyCreator 实现了 BeanFactoryAware 便于底层 IoC 打通,具有依赖查找的能力

    • 通过 getBeanFactory() 获取 BeanFactory
    • setBeanFactory 方法由 Spring IoC 容器回调

    SmartInstantiationAwareBeanPostProcessor 实现

    	@Override
    	@Nullable
    	public Class<?> predictBeanType(Class<?> beanClass, String beanName) {
    		// 如果代理类型缓存为空则跳过
    		if (this.proxyTypes.isEmpty()) {
    			return null;
    		}
    	   /**
             * 如果 bean 名称为空则 cacheKey 则是类对象;
             * 如果有 bean 类型是 FactoryBean 则 cacheKey 则是 &beanName;
             * 否则 cacheKey 就是 beanName
             */
    		Object cacheKey = getCacheKey(beanClass, beanName);
    		// 通过 cacheKey 去代理类型缓存获取
    		return this.proxyTypes.get(cacheKey);
    	}
    	
    	@Override
    	@Nullable
    	public Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName) {
    		return null;
    	}
    	
    	@Override
    	public Object getEarlyBeanReference(Object bean, String beanName) {
    		 /**
             * 如果 bean 名称为空把 bean Class 对象作为 cacheKey ;
             * 如果有 bean 类型是 FactoryBean 则 cacheKey 则是 &beanName;
             * 否则 cacheKey 就是 beanName
             */
    		Object cacheKey = getCacheKey(bean.getClass(), beanName);
    		// 缓存早期代理引用
    		this.earlyProxyReferences.put(cacheKey, bean);
    		// 根据条件生成代理
    		return wrapIfNecessary(bean, beanName, cacheKey);
    	}
    

    获取代理对象

    wrapIfNecessary() 方法分析

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    	// 如果通过了自定义 TargetSourceCreator 方式处理过目标实例则不需要代理
    	if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
    		return bean;
    	}
    	// 内部基础 bean 或者不需要代理的 bean 则不代理
    	if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    		return bean;
    	}
    	/**
    	 * 是否是基础设施(默认规则 Advice、Pointcut、Advisor、AopInfrastructureBean)
    	 * 或者不需要进行代理(默认规则是否是类名与 bean 名称长度必须相同并且 bean 名称以类名开头以 .ORIGINAL)则不代理。并放入 advisedBeans 缓存中
    	 */
    	if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {		// 方入 advisedBean 缓存以便重复创建 bean 时提供性能
    		this.advisedBeans.put(cacheKey, Boolean.FALSE);
    		return bean;
    	}
    	
    	// 根据子类实现不同的规则获取 Advice/Advisor.
    	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    	// 满足生成代理对象条件
    	if (specificInterceptors != DO_NOT_PROXY) {
    		// 放入缓存
    		this.advisedBeans.put(cacheKey, Boolean.TRUE);
    		// 生成代理对象(子类可覆写)
    		Object proxy = createProxy(
    				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    		// 放入代理类型缓存
    		this.proxyTypes.put(cacheKey, proxy.getClass());
    		return proxy;
    	}
    	// 如果没有符合条件的 advice 则不生成代理并缓存
    	this.advisedBeans.put(cacheKey, Boolean.FALSE);
    	return bean;
    }
    

    createProxy() 方法分析

    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    	@Nullable Object[] specificInterceptors, TargetSource targetSource) {
    	/**
    	 *  获取 beanName 的 BeanDefinition 并设置一个
    	 *  属性名为 org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass 值为 beanClass 属性
    	 */
    	if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
    		AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    	}
    	// 通过 ProxyFactory 来创建代理对象
    	ProxyFactory proxyFactory = new ProxyFactory();
    	proxyFactory.copyFrom(this);
    	// 使用 JDK 动态代理
    	if (!proxyFactory.isProxyTargetClass()) {
    	/**
    	 *  通过 beanName 的 BeanDefinition 获取属性名  
    	 *  org.springframework.aop.framework.autoproxy.AutoProxyUtils.originalTargetClass.preserveTargetClass
    	 *  的属性值是否为 true 如果是 true 即使 proxyFactory.isProxyTargetClass() 是 false 还是会使用 CGLIB 动态代理
    	 */
    		if (shouldProxyTargetClass(beanClass, beanName)) {
    			proxyFactory.setProxyTargetClass(true);
    		}
    		else {
    			// 父类 ProxyProcessorSupport#evaluateProxyInterfaces 方法在上面已经分析过了
    			evaluateProxyInterfaces(beanClass, proxyFactory);
    		}
    	}
    	// 构建 Advisor(后面分析)
    	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    	proxyFactory.addAdvisors(advisors);
    	proxyFactory.setTargetSource(targetSource);
    	// 空方法留给子类扩展
    	customizeProxyFactory(proxyFactory);
    	// 是否冻结代理对象(默认是 false)
    	proxyFactory.setFrozen(this.freezeProxy);
    	// 是否对 Advisor 预过滤(默认是 false 留给子类扩展 AbstractAdvisorAutoProxyCreator 是 true)
    	if (advisorsPreFiltered()) {
    		proxyFactory.setPreFiltered(true);
    	}
    	// 通过代理工厂根据 ClassLoader 获取代理对象 
    	return proxyFactory.getProxy(getProxyClassLoader());
    }
    

    buildAdvisors() 方法分析

    确定给定 bean 的 Advisor,包括特定的拦截器和公共拦截器,然后把这些拦截器都适配成 Advisor 对象。

    protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) {
    	/**
    	 * 根据内部关联 BeanFactory 通过 IoC 根据公共的拦截器的 bean 名称获取 bean 
    	 * 然后再通过内部关联的 DefaultAdvisorAdapterRegistry 包装成类型为`DefaultPointcutAdvisor` 的 Advisor
    	 */
    	Advisor[] commonInterceptors = resolveInterceptorNames();
    
    	List<Object> allInterceptors = new ArrayList<>();
    	// 特定的拦截器不为空再根据是否设置了公共拦截器在前,合并这些拦截器
    	if (specificInterceptors != null) {
    		allInterceptors.addAll(Arrays.asList(specificInterceptors));
    		if (commonInterceptors.length > 0) {
    			if (this.applyCommonInterceptorsFirst) {
    				allInterceptors.addAll(0, Arrays.asList(commonInterceptors));
    			}
    			else {
    				allInterceptors.addAll(Arrays.asList(commonInterceptors));
    			}
    		}
    	}
    	
    	Advisor[] advisors = new Advisor[allInterceptors.size()];
    	for (int i = 0; i < allInterceptors.size(); i++) {
    		// 通过内部关联的 DefaultAdvisorAdapterRegistry 把拦截器包装成 Advisor
    		advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i));
    	}
    	return advisors;
    }
    

    子类

    AbstractAdvisorAutoProxyCreator

    自动构建 Advisor 代理列表,子类覆写 findCandidateAdvisors() 获取 Advisor 列表。也可以通过覆写 AbstractAutoProxyCreator.shouldSkip(java.lang.Class<?>, java.lang.String) 方法跳过自动代理。 通过 @Order 注解或者实现 Ordered 接口来控制 Adivosr/Advice。通过 AnnotationAwareOrderComparator 来排序 Advisor/Advice。没有 @Order 注释或没有实现 Ordered 接口的 Advisor 将被认为是无序的;它们将以未定义的顺序出现在 Advisor 链的末尾。

    方法

    getAdvicesAndAdvisorsForBean() 方法

    实现 AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean 方法,委派给本类 findEligibleAdvisors() 方法(子类可以覆写)

    @Override
    @Nullable
    protected Object[] getAdvicesAndAdvisorsForBean(
    	Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    	// 委派给 findEligibleAdvisors() 方法(子类可以覆写)
    	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    	if (advisors.isEmpty()) {
    		return DO_NOT_PROXY;
    	}
    	return advisors.toArray();
    }
    
    findEligibleAdvisors() 方法
    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    	// 通过 IoC 容器获取所有 Advisor 实例
    	List<Advisor> candidateAdvisors = findCandidateAdvisors();
    	/**
    	 *  如果 Advisor 类型是 IntroductionAdvisor 获取关联的 ClassFilter 进行匹配
    	 *  如果 Advisor 类型是 PointcutAdvisor 获取关联的 ClassFilter 进行匹配,如果匹配成功再获取 MethodMatcher 进行静态匹配(2个参数 matches() 方法 )
    	 */
    	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    	// 扩展接口子类实现
    	extendAdvisors(eligibleAdvisors);
    	if (!eligibleAdvisors.isEmpty()) {
    		// 进行排序
    		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    	}
    	return eligibleAdvisors;
    }
    

    AspectJAwareAdvisorAutoProxyCreator

    AbstractAdvisorAutoProxyCreator 子类,它暴露 AspectJ 的调用上下文,并在多个 advice 来自相同的 aspect 时推断 AspectJ 的 advice 优先级规则(AspectJPrecedenceComparator 比较器)。

    主要覆盖方法

    • extendAdvisors:通过 ExposeInvocationInterceptorMethodInvocation 暴露到上下文,以便在 AspectJ 中操作(例如 AbstractAspectJAdvice#currentJoinPoint 方法和 AspectJExpressionPointcut#matches(Method method, Class<?> targetClass, Object… args) 方法)
    • shouldSkip:通过定义的 Aspect
    • sortAdvisors:通过 PartiallyComparableAdvisorHolder 中关联的AnnotationAwareOrderComparator 进行排序

    AnnotationAwareAspectJAutoProxyCreator

    AspectJAwareAdvisorAutoProxyCreator 子类,它处理当前应用上下文用中所有的 AspectJ 中 @Aspect 注解 以及 Spring Advisor ,通过 ReflectiveAspectJAdvisorFactory 和 BeanFactoryAspectJAdvisorsBuilderAdapter 相互搭配实现

    主要覆盖方法

    findCandidateAdvisors() 方法
    @Override
    protected List<Advisor> findCandidateAdvisors() {
    	// 通过 Spring IoC 容器获取所有 Advisor Bean
    	List<Advisor> advisors = super.findCandidateAdvisors();
    	// 通过 Spring IoC 容器获取所有标注 @AspectJ 注解的 Bean,再获取标注 AspectJ 注解(除了@Pointcut 其他的注解 @After、@Before、@AfterReturning 等)的方法
    	if (this.aspectJAdvisorsBuilder != null) {
    		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    	}
    return advisors;
    }
    

    总结

    自动代理创建主要利用 Spring IoC 的 BeanPostProcessor#postProcessAfterInitialization 方法进行扩展,再利用 getAdvicesAndAdvisorsForBean 模板方法根据不同规则获取 Advice/Advisor(比如 Bean 名称,Bean 类型以及 AspectJ ),然后由 ProxyFactory 委派给 DefaultAopProxyFactory(默认,也可以替换)获取代理对象

    展开全文
  • ——小马哥 简介 大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring AOP 编程思想》基础上...
  • CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • ——小马哥 简介 大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring核心编程思想》...
  • 1CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring 过滤器

    2020-11-15 10:18:03
    1CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 1CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • ——小马哥 简介 大家好,我是小马哥成千上万粉丝中的一员!2019年8月有幸在叩丁狼教育举办的猿圈活动中知道有这么一位大咖,从此结下了不解之缘!此系列在多次学习极客时间《小马哥讲Spring核心编程思想》...
  • 小马哥讲Spring 第26章

    2021-02-21 16:06:56
    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring 第25章

    2021-02-07 11:14:12
    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring 第23章

    2021-01-24 22:45:37
    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring 第24章

    2021-01-31 12:24:21
    CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring核心编程思想 第三周 IOC容器概述 Spring实现依赖注入的Java底层技术是Java反射技术。 ICO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,...
  • 跟着小马哥学系列之 Spring AOP(Spring 事务(源码分析)下)简介@EnableTransactionManagement 注解...
  • BeanFactory提供一种高级配置机制,管理底层对象,并不全是Bean ApplicationContext 是 BeanFacotry 子接口 BeanFacotry 是一个底层的IOC容器,ApplicationContext 提供了更多的企业级功能,是BeanFacotry的超集 ...
  • Spring作为IOC容器有什么优势 ? 典型的IOC管理,依赖查找和依赖注入 AOP抽象 事务抽象 ...2,ObjectFactory 和 BeanFactory ...beanFactory是一个底层的容器 applicationContext是在他的基础上新增了一些功能
  • CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让调用类...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。
  • 小马哥讲Spring核心编程思想 第十五周 Spring注解实现 待补充,因时间较紧,后续补充。01-03 课程介绍,内容综述,课前准备04丨特性总览:核心特性、数据存储、Web技术、框架整合与测试05丨Spring版本特性:Spring...
  • 1CO:Spring容器的内核,AOP、声明式事务等功能都基于此产生。 ICO不够开门见山,所以后期由Martin Fowler用DI,依赖注入的概念代替了IoC,让...JDK所提供的访问资源的类并不能很好地满足各种底层资源的访问需求。Sprin
  • 一年了,大家还记得那位退隐CV江湖的YOLO之父“小马哥”吗? 可能搞目标检测的,或者说搞计算机视觉的,都知道一个叫YOLO的系列工作。YOLO是You Only Look Once的缩写,即“你只需要看一次”。 YOLO可以说是计算机...
  • 小马哥最让我佩服的地方,就是他的风格“务实、讲明白、用得上”,没有废话,通俗易懂,这次的《小马哥讲 Spring AOP 编程思想》视频课,力求打造最实用的 Spring AOP 课程,深挖其内在原理和实现层面,逐个击破,...
  • 现在市场百分80被安卓手机所占领。Mtk芯片6575 6577 6572 6582 6589 6592 6591 6595等芯片手机,所对应的mtk刷机平台SP_Flash_Tool_exe随着芯片核心的升级对应的刷机平台相应的...转载请注明作者:小马哥

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 674
精华内容 269
关键字:

小马哥底层