Spring AOP源码学习:创建 AOP 代理

// 2.遍历处理advisorNames

List advisors = new LinkedList();

for (String name : advisorNames) {

if (isEligibleBean(name)) {

// 2.1 跳过当前正在创建的advisor

if (this.beanFactory.isCurrentlyInCreation(name)) {

if (logger.isDebugEnabled()) {

logger.debug(“Skipping currently created advisor '” + name + “'”);

}

} else {

try {

// 2.2 通过beanName获取对应的bean对象,并添加到advisors

advisors.add(this.beanFactory.getBean(name, Advisor.class));

} catch (BeanCreationException ex) {

Throwable rootCause = ex.getMostSpecificCause();

if (rootCause instanceof BeanCurrentlyInCreationException) {

BeanCreationException bce = (BeanCreationException) rootCause;

if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {

if (logger.isDebugEnabled()) {

logger.debug(“Skipping advisor '” + name +

"’ with dependency on currently created bean: " + ex.getMessage());

}

// Ignore: indicates a reference back to the bean we’re trying to advise.

// We want to find advisors other than the currently created bean itself.

continue;

}

}

throw ex;

}

}

}

}

// 3.返回符合条件的advisor列表

return advisors;

}

代码块6:buildAspectJAdvisors


public List buildAspectJAdvisors() {

List aspectNames = this.aspectBeanNames;

// 1.如果aspectNames为空,则进行解析

if (aspectNames == null) {

synchronized (this) {

aspectNames = this.aspectBeanNames;

if (aspectNames == null) {

List advisors = new LinkedList();

aspectNames = new LinkedList();

// 1.1 获取所有的beanName

String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(

this.beanFactory, Object.class, true, false);

// 1.2 循环遍历所有的beanName,找出对应的增强方法

for (String beanName : beanNames) {

// 1.3 不合法的beanName则跳过,默认返回true,子类可以覆盖实现,AnnotationAwareAspectJAutoProxyCreator

// 实现了自己的逻辑,支持使用includePatterns进行筛选

if (!isEligibleBean(beanName)) {

continue;

}

// We must be careful not to instantiate beans eagerly as in this case they

// would be cached by the Spring container but would not have been weaved.

// 获取beanName对应的bean的类型

Class<?> beanType = this.beanFactory.getType(beanName);

if (beanType == null) {

continue;

}

// 1.4 如果beanType存在Aspect注解则进行处理

if (this.advisorFactory.isAspect(beanType)) {

// 将存在Aspect注解的beanName添加到aspectNames列表

aspectNames.add(beanName);

// 新建切面元数据

AspectMetadata amd = new AspectMetadata(beanType, beanName);

// 获取per-clause的类型是SINGLETON

if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

// 使用BeanFactory和beanName创建一个BeanFactoryAspectInstanceFactory,主要用来创建切面对象实例

MetadataAwareAspectInstanceFactory factory =

new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);

// 1.5 解析标记AspectJ注解中的增强方法

List classAdvisors = this.advisorFactory.getAdvisors(factory);

// 1.6 放到缓存中

if (this.beanFactory.isSingleton(beanName)) {

// 如果beanName是单例则直接将解析的增强方法放到缓存

this.advisorsCache.put(beanName, classAdvisors);

} else {

// 如果不是单例,则将factory放到缓存,之后可以通过factory来解析增强方法

this.aspectFactoryCache.put(beanName, factory);

}

// 1.7 将解析的增强器添加到advisors

advisors.addAll(classAdvisors);

} else {

// 如果per-clause的类型不是SINGLETON

// Per target or per this.

if (this.beanFactory.isSingleton(beanName)) {

// 名称为beanName的Bean是单例,但切面实例化模型不是单例,则抛异常

throw new IllegalArgumentException(“Bean with name '” + beanName +

“’ is a singleton, but aspect instantiation model is not singleton”);

}

MetadataAwareAspectInstanceFactory factory =

new PrototypeAspectInstanceFactory(this.beanFactory, beanName);

// 将factory放到缓存,之后可以通过factory来解析增强方法

this.aspectFactoryCache.put(beanName, factory);

// 解析标记AspectJ注解中的增强方法,并添加到advisors中

advisors.addAll(this.advisorFactory.getAdvisors(factory));

}

}

}

// 1.9 将解析出来的切面beanName放到缓存aspectBeanNames

this.aspectBeanNames = aspectNames;

// 1.10 最后返回解析出来的增强器

return advisors;

}

}

}

// 2.如果aspectNames不为null,则代表已经解析过了,则无需再次解析

// 2.1 如果aspectNames是空列表,则返回一个空列表。空列表也是解析过的,只要不是null都是解析过的。

if (aspectNames.isEmpty()) {

return Collections.emptyList();

}

// 2.2 aspectNames不是空列表,则遍历处理

List advisors = new LinkedList();

for (String aspectName : aspectNames) {

// 根据aspectName从缓存中获取增强器

List cachedAdvisors = this.advisorsCache.get(aspectName);

if (cachedAdvisors != null) {

// 根据上面的解析,可以知道advisorsCache存的是已经解析好的增强器,直接添加到结果即可

advisors.addAll(cachedAdvisors);

} else {

// 如果不存在于advisorsCache缓存,则代表存在于aspectFactoryCache中,

// 从aspectFactoryCache中拿到缓存的factory,然后解析出增强器,添加到结果中

MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);

advisors.addAll(this.advisorFactory.getAdvisors(factory));

}

}

// 返回增强器

return advisors;

}

1.5 解析标记 AspectJ 注解中的增强方法,见代码块7。

代码块7:getAdvisors


@Override

public List getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {

// 1.前面我们将beanClass和beanName封装成了aspectInstanceFactory的AspectMetadata属性,

// 这边可以通过AspectMetadata属性重新获取到当前处理的切面类

Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();

// 2.获取当前处理的切面类的名字

String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();

// 3.校验切面类

validate(aspectClass);

// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator

// so that it will only instantiate once.

// 4.使用装饰器包装MetadataAwareAspectInstanceFactory,以便它只实例化一次。

MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =

new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

List advisors = new LinkedList();

// 5.获取切面类中的方法(也就是我们用来进行逻辑增强的方法,被@Around、@After等注解修饰的方法,使用@Pointcut的方法不处理)

for (Method method : getAdvisorMethods(aspectClass)) {

// 6.处理method,获取增强器

Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

if (advisor != null) {

// 7.如果增强器不为空,则添加到advisors

advisors.add(advisor);

}

}

// If it’s a per target aspect, emit the dummy instantiating aspect.

if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {

// 8.如果寻找的增强器不为空而且又配置了增强延迟初始化,那么需要在首位加入同步实例化增强器(用以保证增强使用之前的实例化)

Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);

advisors.add(0, instantiationAdvisor);

}

// Find introduction fields.

// 9.获取DeclareParents注解

for (Field field : aspectClass.getDeclaredFields()) {

Advisor advisor = getDeclareParentsAdvisor(field);

if (advisor != null) {

advisors.add(advisor);

}

}

return advisors;

}

6.处理 method,获取增强器,见代码块8。

代码块8:getAdvisor


@Override

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,

int declarationOrderInAspect, String aspectName) {

// 1.校验切面类

validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());

// 2.AspectJ切点信息的获取(例如:表达式),就是指定注解的表达式信息的获取,如:@Around(“execution(* com.joonwhee.open.aop..(…))”)

AspectJExpressionPointcut expressionPointcut = getPointcut(

candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());

// 3.如果expressionPointcut为null,则直接返回null

if (expressionPointcut == null) {

return null;

}

// 4.根据切点信息生成增强器

return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,

this, aspectInstanceFactory, declarationOrderInAspect, aspectName);

}

2.AspectJ 切点信息的获取,见代码块9。

4.根据切点信息生成增强器,见代码块11。

代码块9:getPointcut


private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {

// 1.查找并返回给定方法的第一个AspectJ注解(@Before, @Around, @After, @AfterReturning, @AfterThrowing, @Pointcut)

// 因为我们之前把@Pointcut注解的方法跳过了,所以这边必然不会获取到@Pointcut注解

AspectJAnnotation<?> aspectJAnnotation =

AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);

// 2.如果方法没有使用AspectJ的注解,则返回null

if (aspectJAnnotation == null) {

return null;

}

// 3.使用AspectJExpressionPointcut实例封装获取的信息

AspectJExpressionPointcut ajexp =

new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);

// 提取得到的注解中的表达式,

// 例如:@Around(“execution(* com.joonwhee.open.aop..(…))”),得到:execution(* com.joonwhee.open.aop..(…))

ajexp.setExpression(aspectJAnnotation.getPointcutExpression());

ajexp.setBeanFactory(this.beanFactory);

return ajexp;

}

1.获取方法上的AspectJ注解,见代码块10。

代码块10:findAspectJAnnotationOnMethod


protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {

// 设置要查找的注解类

Class<?>[] classesToLookFor = new Class<?>[]{

Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};

for (Class<?> c : classesToLookFor) {

// 查找方法上是否存在当前遍历的注解,如果有则返回

AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class) c);

if (foundAnnotation != null) {

return foundAnnotation;

}

}

return null;

}

代码块11:new InstantiationModelAwarePointcutAdvisorImpl


public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,

Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,

MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

// 1.简单的将信息封装在类的实例中

this.declaredPointcut = declaredPointcut;

this.declaringClass = aspectJAdviceMethod.getDeclaringClass();

this.methodName = aspectJAdviceMethod.getName();

this.parameterTypes = aspectJAdviceMethod.getParameterTypes();

// aspectJAdviceMethod保存的是我们用来进行逻辑增强的方法(@Around、@After等修饰的方法)

this.aspectJAdviceMethod = aspectJAdviceMethod;

this.aspectJAdvisorFactory = aspectJAdvisorFactory;

this.aspectInstanceFactory = aspectInstanceFactory;

this.declarationOrder = declarationOrder;

this.aspectName = aspectName;

// 2.是否需要延迟实例化

if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {

// Static part of the pointcut is a lazy type.

Pointcut preInstantiationPointcut = Pointcuts.union(

aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.

// If it’s not a dynamic pointcut, it may be optimized out

// by the Spring AOP infrastructure after the first evaluation.

this.pointcut = new PerTargetInstantiationModelPointcut(

this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);

this.lazy = true;

} else {

// A singleton aspect.

this.pointcut = this.declaredPointcut;

this.lazy = false;

// 3.实例化增强器:根据注解中的信息初始化对应的增强器

this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);

}

}

3.实例化增强器:根据注解中的信息初始化对应的增强器,见代码块12。

代码块12:instantiateAdvice


private Advice instantiateAdvice(AspectJExpressionPointcut pcut) {

return this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pcut,

this.aspectInstanceFactory, this.declarationOrder, this.aspectName);

}

// ReflectiveAspectJAdvisorFactory.java

@Override

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,

MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

// 1.获取切面类

Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();

// 2.校验切面类(重复校验第3次…)

validate(candidateAspectClass);

// 3.查找并返回方法的第一个AspectJ注解

AspectJAnnotation<?> aspectJAnnotation =

AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);

if (aspectJAnnotation == null) {

return null;

}

// If we get here, we know we have an AspectJ method.

// Check that it’s an AspectJ-annotated class

// 4.如果我们到这里,我们知道我们有一个AspectJ方法。检查切面类是否使用了AspectJ注解

if (!isAspect(candidateAspectClass)) {

throw new AopConfigException("Advice must be declared inside an aspect type: " +

“Offending method '” + candidateAdviceMethod + “’ in class [” +

candidateAspectClass.getName() + “]”);

}

if (logger.isDebugEnabled()) {

logger.debug("Found AspectJ method: " + candidateAdviceMethod);

}

AbstractAspectJAdvice springAdvice;

// 5.根据方法使用的aspectJ注解创建对应的增强器,例如最常见的@Around注解会创建AspectJAroundAdvice

switch (aspectJAnnotation.getAnnotationType()) {

case AtBefore:

springAdvice = new AspectJMethodBeforeAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

case AtAfter:

springAdvice = new AspectJAfterAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

case AtAfterReturning:

springAdvice = new AspectJAfterReturningAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();

if (StringUtils.hasText(afterReturningAnnotation.returning())) {

springAdvice.setReturningName(afterReturningAnnotation.returning());

}

break;

case AtAfterThrowing:

springAdvice = new AspectJAfterThrowingAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();

if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {

springAdvice.setThrowingName(afterThrowingAnnotation.throwing());

}

break;

case AtAround:

springAdvice = new AspectJAroundAdvice(

candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);

break;

case AtPointcut:

if (logger.isDebugEnabled()) {

logger.debug(“Processing pointcut '” + candidateAdviceMethod.getName() + “'”);

}

return null;

default:

throw new UnsupportedOperationException(

"Unsupported advice type on method: " + candidateAdviceMethod);

}

// Now to configure the advice…

// 6.配置增强器

// 切面类的name,其实就是beanName

springAdvice.setAspectName(aspectName);

springAdvice.setDeclarationOrder(declarationOrder);

// 获取增强方法的参数

String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);

if (argNames != null) {

// 如果参数不为空,则赋值给springAdvice

springAdvice.setArgumentNamesFromStringArray(argNames);

}

springAdvice.calculateArgumentBindings();

// 最后,返回增强器

return springAdvice;

}

代码块13:findAdvisorsThatCanApply


public static List findAdvisorsThatCanApply(List candidateAdvisors, Class<?> clazz) {

if (candidateAdvisors.isEmpty()) {

return candidateAdvisors;

}

List eligibleAdvisors = new LinkedList();

// 1.首先处理引介增强(@DeclareParents)用的比较少可以忽略,有兴趣的参考:https://www.cnblogs.com/HigginCui/p/6322283.html

for (Advisor candidate : candidateAdvisors) {

if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {

eligibleAdvisors.add(candidate);

}

}

boolean hasIntroductions = !eligibleAdvisors.isEmpty();

// 2.遍历所有的candidateAdvisors

for (Advisor candidate : candidateAdvisors) {

// 2.1 引介增强已经处理,直接跳过

if (candidate instanceof IntroductionAdvisor) {

// already processed

continue;

}

// 2.2 正常增强处理,判断当前bean是否可以应用于当前遍历的增强器(bean是否包含在增强器的execution指定的表达式中)

if (canApply(candidate, clazz, hasIntroductions)) {

eligibleAdvisors.add(candidate);

}

}

return eligibleAdvisors;

}

2.2 正常增强处理,判断当前 bean 是否可以应用于当前遍历的增强器,这边表达式判断的逻辑比较复杂,可以简单的理解为:判断 bean 是否包含在增强器的 execution 指定的表达式中。

代码块14:createProxy


protected Object createProxy(

Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

if (this.beanFactory instanceof ConfigurableListableBeanFactory) {

AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);

}

// 1.初始化ProxyFactory

ProxyFactory proxyFactory = new ProxyFactory();

// 从当前对象复制属性值

proxyFactory.copyFrom(this);

// 检查proxyTargetClass属性,判断对于给定的bean使用类代理还是接口代理,

// proxyTargetClass值默认为false,可以通过proxy-target-class属性设置为true

if (!proxyFactory.isProxyTargetClass()) {

// 检查preserveTargetClass属性,判断beanClass是应该基于类代理还是基于接口代理

if (shouldProxyTargetClass(beanClass, beanName)) {

// 如果是基于类代理,则将proxyTargetClass赋值为true

proxyFactory.setProxyTargetClass(true);

} else {

// 评估bean的代理接口

evaluateProxyInterfaces(beanClass, proxyFactory);

}

}

// 将拦截器封装为Advisor(advice持有者)

Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);

// 将advisors添加到proxyFactory

proxyFactory.addAdvisors(advisors);

// 设置要代理的类,将targetSource赋值给proxyFactory的targetSource属性,之后可以通过该属性拿到被代理的bean的实例

proxyFactory.setTargetSource(targetSource);

// 自定义ProxyFactory,空方法,留给子类实现

customizeProxyFactory(proxyFactory);

// 用来控制proxyFactory被配置之后,是否还允许修改通知。默认值为false(即在代理被配置之后,不允许修改代理类的配置)

proxyFactory.setFrozen(this.freezeProxy);

if (advisorsPreFiltered()) {

proxyFactory.setPreFiltered(true);

}

// 2.使用proxyFactory获取代理

return proxyFactory.getProxy(getProxyClassLoader());

}

2.使用 proxyFactory 获取代理,见代码块15。

代码块15:getProxy


public Object getProxy(ClassLoader classLoader) {

// 1.createAopProxy:创建AopProxy

// 2.getProxy(classLoader):获取代理对象实例

return createAopProxy().getProxy(classLoader);

}

1.createAopProxy:创建AopProxy,见代码块16。

2.getProxy(classLoader):获取代理对象实例,跟我们自己写的代理类似,JDK 动态代理见代码块18,CGLIB 代理见代码块19。

代码块16:createAopProxy


protected final synchronized AopProxy createAopProxy() {

if (!this.active) {

// 1.激活此代理配置

activate();

}

// 2.创建AopProxy

return getAopProxyFactory().createAopProxy(this);

}

@Override

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

// 1.判断使用JDK动态代理还是Cglib代理

// optimize:用于控制通过cglib创建的代理是否使用激进的优化策略。除非完全了解AOP如何处理代理优化,

// 否则不推荐使用这个配置,目前这个属性仅用于cglib代理,对jdk动态代理无效

// proxyTargetClass:默认为false,设置为true时,强制使用cglib代理,设置方式:<aop:aspectj-autoproxy proxy-target-class=“true” />

// hasNoUserSuppliedProxyInterfaces:config是否存在代理接口或者只有SpringProxy一个接口

if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {

// 拿到要被代理的对象的类型

Class<?> targetClass = config.getTargetClass();

if (targetClass == null) {

// TargetSource无法确定目标类:代理创建需要接口或目标。

throw new AopConfigException("TargetSource cannot determine target class: " +

“Either an interface or a target is required for proxy creation.”);

}

// 要被代理的对象是接口 || targetClass是Proxy class

// 当且仅当使用getProxyClass方法或newProxyInstance方法动态生成指定的类作为代理类时,才返回true。

if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {

// JDK动态代理,这边的入参config(AdvisedSupport)实际上是ProxyFactory对象

// 具体为:AbstractAutoProxyCreator中的proxyFactory.getProxy发起的调用,在ProxyCreatorSupport使用了this作为参数,

// 调用了的本方法,这边的this就是发起调用的proxyFactory对象,而proxyFactory对象中包含了要执行的的拦截器

return new JdkDynamicAopProxy(config);

}

// Cglib代理

return new ObjenesisCglibAopProxy(config);

} else {

// JDK动态代理

return new JdkDynamicAopProxy(config);

}

}

这边创建 AopProxy 的参数 config(AdvisedSupport)实际上是代码块14中的 proxyFactory 对象。

具体为:AbstractAutoProxyCreator 中的 proxyFactory.getProxy 发起的调用,在 ProxyCreatorSupport 使用了 this 作为参数调用了本方法,这边的 this 就是发起调用的 proxyFactory对象,而 proxyFactory 对象中包含了要执行的的拦截器(Advisor)。

无论是创建 JDK 动态代理还是 CGLIB 代理,都会传入 config 参数,该参数会被保存在 advised(AdvisedSupport)变量中,见代码块17。

代码块17:JDK 动态代理、CBLIB 代理构造函数


// JdkDynamicAopProxy.java

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {

Assert.notNull(config, “AdvisedSupport must not be null”);

if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {

throw new AopConfigException(“No advisors and no TargetSource specified”);

}

// config赋值给advised

this.advised = config;

}

// ObjenesisCglibAopProxy.java

public ObjenesisCglibAopProxy(AdvisedSupport config) {

super(config);

}

// CglibAopProxy.java

public CglibAopProxy(AdvisedSupport config) throws AopConfigException {

Assert.notNull(config, “AdvisedSupport must not be null”);

if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {

throw new AopConfigException(“No advisors and no TargetSource specified”);

}

this.advised = config;

this.advisedDispatcher = new AdvisedDispatcher(this.advised);

}

代码块18:JdkDynamicAopProxy#getProxy


@Override

public Object getProxy(ClassLoader classLoader) {

if (logger.isDebugEnabled()) {

logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());

}

// 1.拿到要被代理对象的所有接口

Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);

findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

// 2.通过classLoader、接口、InvocationHandler实现类,来获取到代理对象

return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);

}

最终,通过 JDK 动态代理的类被调用时,会走到 JdkDynamicAopProxy#invoke 方法。

代码块19:CglibAopProxy#getProxy


@Override

public Object getProxy(ClassLoader classLoader) {

if (logger.isDebugEnabled()) {

logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());

}

try {

// 1.拿到要代理目标类

Class<?> rootClass = this.advised.getTargetClass();

Assert.state(rootClass != null, “Target class must be available for creating a CGLIB proxy”);

// proxySuperClass默认为rootClass

Class<?> proxySuperClass = rootClass;

if (ClassUtils.isCglibProxyClass(rootClass)) {

// 如果rootClass是被Cglib代理过的,获取rootClass的父类作为proxySuperClass

proxySuperClass = rootClass.getSuperclass();

Class<?>[] additionalInterfaces = rootClass.getInterfaces();

for (Class<?> additionalInterface : additionalInterfaces) {

// 将父类的接口也添加到advised的interfaces属性

this.advised.addInterface(additionalInterface);

}

}

// Validate the class, writing log messages as necessary.

// 2.校验proxySuperClass,主要是校验方法是否用final修饰、跨ClassLoader的包可见方法,如果有将警告写入日志

validateClassIfNecessary(proxySuperClass, classLoader);

// Configure CGLIB Enhancer…

// 3.创建和配置Cglib Enhancer

Enhancer enhancer = createEnhancer();

if (classLoader != null) {

enhancer.setClassLoader(classLoader);

if (classLoader instanceof SmartClassLoader &&

((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {

enhancer.setUseCache(false);

}

}

// superclass为被代理的目标类proxySuperClass,通过名字可以看出,生成的代理类实际上是继承了被代理类

enhancer.setSuperclass(proxySuperClass);

enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));

enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);

enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

// 4.获取所有要回调的拦截器

Callback[] callbacks = getCallbacks(rootClass);

Class<?>[] types = new Class<?>[callbacks.length];

for (int x = 0; x < types.length; x++) {

types[x] = callbacks[x].getClass();

}

// fixedInterceptorMap only populated at this point, after getCallbacks call above

// 在上面调用getCallbacks之后,此时仅填充fixedInterceptorMap

enhancer.setCallbackFilter(new ProxyCallbackFilter(

this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));

enhancer.setCallbackTypes(types);

// Generate the proxy class and create a proxy instance.

// 5.生成代理类并创建代理实例,返回代理实例

return createProxyClassAndInstance(enhancer, callbacks);

} catch (CodeGenerationException ex) {

throw new AopConfigException(“Could not generate CGLIB subclass of class [” +

this.advised.getTargetClass() + "]: " +

“Common causes of this problem include using a final class or a non-visible class”,

ex);

} catch (IllegalArgumentException ex) {

throw new AopConfigException(“Could not generate CGLIB subclass of class [” +

this.advised.getTargetClass() + "]: " +

“Common causes of this problem include using a final class or a non-visible class”,

ex);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

面试题总结

其它面试题(springboot、mybatis、并发、java中高级面试总结等)

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
tTargetClass() + "]: " +

“Common causes of this problem include using a final class or a non-visible class”,

ex);

} catch (IllegalArgumentException ex) {

throw new AopConfigException(“Could not generate CGLIB subclass of class [” +

this.advised.getTargetClass() + "]: " +

“Common causes of this problem include using a final class or a non-visible class”,

ex);

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-eWSphKQ6-1713290293701)]

[外链图片转存中…(img-BO3SCNVr-1713290293702)]

[外链图片转存中…(img-Gaachegk-1713290293702)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

面试题总结

其它面试题(springboot、mybatis、并发、java中高级面试总结等)

[外链图片转存中…(img-hOZUF6AU-1713290293702)]

[外链图片转存中…(img-OQGFQOnr-1713290293702)]

[外链图片转存中…(img-QrbR5DKw-1713290293703)]

《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

  • 21
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值