Spring AOP源码解析二: 根据普通bean创建其动态代理

       根据Spring AOP源码解析一 里面所讲的内容,在Spring容器启动时,会先创建所有的bean的后置处理器,然后再创建普通bean的时候,在合适的地方调用bean的后置处理器执行相应的逻辑,而对于普通bean在Spring执行的生命周期的initializeBean方法中进行完成AOP动态代理的功能工作。

       说源码前首先需要有个案例:

       Config 配置类,定义扫描规则和注入AOP切面处理类

package com.luban.aop;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.luban.aop")
@EnableAspectJAutoProxy
public class Config {
}

       UserService 类,该类为要代理的类

package com.luban.aop.service;
import org.springframework.stereotype.Service;
@Service
public class UserService {

	public String getName(){
		System.out.println("getName");
		return "wj";
	}

	public void sayHello(){
		System.out.println("hello");
	}
}

        MyAspect 类,该类为切换类,定义的切点,这个切面类之所以写的这么复杂,是因为最大可能的还原真实场景,但是也是有差距的,getPointcut这个切点是作用在com.luban.aop.service包或者是子包下面所有类以get开头的所有方法,而pointcut切点会作用在com.luban.aop.service包或者是子包下面所有类的所有方法。

package com.luban.aop;

import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {
    @Pointcut("execution(* com.luban.aop.service..*.get*(..))")
    public void getPointcut() {
    }

    @Before("getPointcut()")
    public void before() {
        System.out.println("before advice");
    }

    @After("getPointcut()")
    public void after() {
        System.out.println("after advice");
    }

    @Pointcut("execution(* com.luban.aop.service..*.*(..))")
    public void pointcut() {
    }

    @AfterReturning("pointcut()")
    public void AfterReturning() {
        System.out.println("AfterReturning advice");
    }

    @Pointcut("execution(* com.luban.aop.service1..*.*(..))")
    public void pointcut1() {
    }

    @AfterReturning("pointcut1()")
    public void AfterReturning1() {
        System.out.println("AfterReturning advice");
    }

    @After("pointcut1()")
    public void after1() {
        System.out.println("after advice");
    }
}

        测试类,主要是启动类,用来测试

package com.luban.aop;

import com.luban.aop.service.UserService;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Test01 {
	public static void main(String[] args) {
		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
		UserService bean = context.getBean(UserService.class);
		bean.getName();
	}
}

      定义之后,在后面的讲解中会使用到上面案例作为说明,这样能够讲的更清晰。

       关于Spring bean创建的流程这里就不再细说了,感兴趣的先参考:Spring中bean的生命周期(最详细),这里仅对Spring AOP进行分析,那么我们的切入点就从initializeBean方法讲起,具体看代码块1。

代码块1:AbstractAutowireCapableBeanFactory#initializeBean方法

protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
	//1.以安全的方式执行Aware接口的回调方法,进行设置bean工厂、bean的类加载器、bean的名称
	//具体看invokeAwareMethods方法
	if (System.getSecurityManager() != null) {
		AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
			invokeAwareMethods(beanName, bean);
			return null;
		}, getAccessControlContext());
	}
	else {
		invokeAwareMethods(beanName, bean);
	}
	//2.执行所有的bean的后置处理的postProcessBeforeInitialization方法
	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	//3.执行bean的初始化
	try {
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	//4.执行所有的bean的后置处理的postProcessorsAfterInitialization方法,也是在此步骤完成bean的动态代理
	if (mbd == null || !mbd.isSynthetic()) {
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

private void invokeAwareMethods(final String beanName, final Object bean) {
	if (bean instanceof Aware) {
		if (bean instanceof BeanNameAware) {
			((BeanNameAware) bean).setBeanName(beanName);
		}
		if (bean instanceof BeanClassLoaderAware) {
			ClassLoader bcl = getBeanClassLoader();
			if (bcl != null) {
				((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
			}
		}
		if (bean instanceof BeanFactoryAware) {
			((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
		}
	}
}

        关于第1、2、3不是本次讲解的重要,如果真要细说的话,就这三个步骤就可以讲解一篇博客,主要是第4步,这一步会调用所有的bean的后置处理的postProcessorsAfterInitialization方法,也就是在此步完成AOP动态代理的操作,关于第4步的请看代码块2.

代码块2:AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
		throws BeansException {
	//1.已存在bean,这个bean是没有代理之前的bean
	Object result = existingBean;
	//2.拿到所有的bena的后置处理器,依次进行遍历
	for (BeanPostProcessor processor : getBeanPostProcessors()) {
		//3.执行其postProcessAfterInitialization方法
		Object current = processor.postProcessAfterInitialization(result, beanName);
		//4.如果有其中一个返回空,则就直接返回了,不再进行遍历
		if (current == null) {
			return result;
		}
		result = current;
	}
	return result;
}

       第3步执行后置处理器的postProcessAfterInitialization方法,并将返回的current 对象赋值给result,也就是会替换原来的bean对象。而对于bean后置处理器的postProcessAfterInitialization方法,如果不做处理的话,都是直接将传递过来的bean给直接返回,而不进行任何处理。

      对于上篇文章提到的AnnotationAwareAspectJAutoProxyCreator也是一个bean后置处理器,而AnnotationAwareAspectJAutoProxyCreator间接的继承AbstractAutoProxyCreator类,在AbstractAutoProxyCreator类中实现了postProcessAfterInitialization方法,具体看代码块3.

代码块3:AbstractAutoProxyCreator#postProcessAfterInitialization方法 

/**
 * Create a proxy with the configured interceptors if the bean is
 * identified as one to proxy by the subclass.
 * 如果子类将bean标识为一个要代理的bean,则使用配置的拦截器创建一个代理
 * @see #getAdvicesAndAdvisorsForBean
 */
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, St
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值