注:本文参考《Spring源码深度解析》,结合代码实际讲述AOP过程实现。具体步骤请参考目录分层,可以让阅读更清晰,因为Spring代码封装比较强,需分层级方能更好理解
Spring AOP的具体实现可以查看下面这个图
1.注册切面处理器
AOP的处理器注册在AopNamespaceHandler这个类中,我们直接进来查看
public class AopNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
/**
* 注册一个切面处理器
* registerBeanDefinitionParser其实就是构造一个对应的key-value的结构
*/
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
//------其他的注册信息,不管
}
}
2.1 BeanDefinitionParser的parse操作
因为AspectJAutoProxyBeanDefinitionParser是继承自BeanDefinitionParser,所以需要实现的是她的parse方法,我们来看这边的具体操作.往下去分析每一个函数的具体操作
/**
* 这个接口是实现了BeanDefinitionParser接口,所以他的入口在这边
*/
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
/**
* 注册 AnnotationAwareAspectJAutoProxyCreator,这个是我们的关键类
*/
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);
/**
* 对注解中子类的处理
*/
extendBeanDefinition(element, parserContext);
return null;
}
3.1 注册构造器
主要看第一个注册的方法.
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
/**
* 这边会去注册一个AnnotationAwareAspectJAutoProxyCreator类,这个类应该是主要做AOP的@Point注解解析的
*/
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext.getRegistry(),
parserContext.extractSource(sourceElement));
/**
* proxy-target-class属性和expose proxy属性的处理
*/
useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
/**
* 注册组件
*/
registerComponentIfNecessary(beanDefinition, parserContext);
}
4.1 注册 AnnotationAwareAspectJAutoProxyCreator
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
/**
* 这边可以看到他是传入一个AnnotationAwareAspectJAutoProxyCreator的class对象
*/
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
5.1 存在两个构造器的处理
存在两个构造器,这边会根据优先级去拿到高的构造器
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
/**
* 如果已经存在对应的自动代理创造器,并且两个不一致,根据优先级Priority来判断使用哪个
*/
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
int requiredPriority = findPriorityForClass(cls);
if (currentPriority < requiredPriority) {
apcDefinition.setBeanClassName(cls.getName());
}
}
return null;
}
//---------------------略
}
5.2 不存在构造器
如果不存在构造器则会去创建一个并注册,其实就是放入容器的操作
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//---------------------略
/**
* 不存在该创造器,则会去注册一个
*/
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
/**
* 这边就是具体的注册,应该是BeanDefinitionRegister的具体实现类往容器添加这个创造器吧
*/
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
4.2 proxy-target-class属性和expose proxy属性处理
这边就是实现两个属性获取和设值的操作
private static void useClassProxyingIfNecessary(BeanDefinitionRegistry registry, Element sourceElement) {
if (sourceElement != null) {
boolean proxyTargetClass = Boolean.valueOf(sourceElement.getAttribute(PROXY_TARGET_CLASS_ATTRIBUTE));
if (proxyTargetClass) {
/**
* 10.proxy-target-class属性的处理--强制使用CGLIB代理(true).
*/
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
boolean exposeProxy = Boolean.valueOf(sourceElement.getAttribute(EXPOSE_PROXY_ATTRIBUTE));
if (exposeProxy) {
/**
* 11.expose-proxy属性的处理
*/
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry) {
/**
* 13.对属性的一个设置
*/
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
}
}
public static void forceAutoProxyCreatorToExposeProxy(BeanDefinitionRegistry registry) {
if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
definition.getPropertyValues().add("exposeProxy", Boolean.TRUE);
}
}
4.3 注册组件
往容器中添加组件
private static void registerComponentIfNecessary(BeanDefinition beanDefinition, ParserContext parserContext) {
if (beanDefinition != null) {
BeanComponentDefinition componentDefinition =
new BeanComponentDefinition(beanDefinition, AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
parserContext.registerComponent(componentDefinition);
}
}
3.2 其他构造器的处理
这边的操作是往每一个节点去添加对应的BeanDefinition.我们主要还是关注在上面的操作
private void extendBeanDefinition(Element element, ParserContext parserContext) {
/**
* 15.添加子节点的对应BeanDefinition
*/
BeanDefinition beanDef = parserContext.getRegistry().getBeanDefinition(AopConfigUtils.AUTO_PROXY_CREATOR_BEAN_NAME);
if (element.hasChildNodes()) {
addIncludePatterns(element, parserContext, beanDef);
}
}
到这边位置,我们的构造器已经添加到容器中,下面就是看他具体是怎么处理的.
2.切面构造器AnnotationAwareAspectJAutoProxyCreator的处理
我们来看一下构造器的继承关系,一直往上,他其实是实现了BeanPostProcessor这个接口,实现该接口就回去实现他的postProcessAfterInitialization方法,这也是我们需要重点关注的地方.
3.1关于BeanPostProcessor
关于BeanPostProcessor这个接口其实是做了Bean调用的增强,在网上找了一个图,大概表示这个增强过程
3.2 postProcessAfterInitialization的处理
postProcessAfterInitialization这个方法的实现,我们要追索到继承下来的AbstractAutoProxyCreator这个类.
4.1 缓存查找存在key
如果能找到key对应的Object则直接返回
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
/**
* 只是一个简单的key构造的操作,key为:beanClassName_beanName
*/
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//..............略
}
}
return bean;
}
4.2 缓存查找不存在key
找不到对应的object,则进入包装方法
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean != null) {
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
/**
* 如果这个key不存在,则封装成对应的对象返回
*/
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
5.1 不需要处理的情况
这边描述了四种不需要处理的情况
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
/**
* 不需要代理的情况:1.已经处理过了2.无需增强3.基础设施类4.已配置了bean
*/
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
//..................略
}
5.2 获取Advisor增强方法数组
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//...............略
/**
* 获取增强方法
* @see org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
*/
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(),beanName, null);
//...............略
}
直接查看AbstractAdvisorAutoProxyCreator类对#getAdvicesAndAdvisorsForBean的实现
@Override
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
/**
* 通过这个方法去获取增强方法对象数组
*/
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
6.1 查找所有Advisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
/**
* @see AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors()
*/
List<Advisor> candidateAdvisors = findCandidateAdvisors();
//............略
}
直接查看AnnotationAwareAspectJAutoProxyCreator对这个方法的重写
这边保留了父类对xml配置的切面查找的操作,并引入注解式配置的查找
@Override
protected List<Advisor> findCandidateAdvisors() {
/**
* 这边依然会去调用父类的xml方式查找advisor的操作
*/
List<Advisor> advisors = super.findCandidateAdvisors();
/**
* 这边查找注解式的advisor增强方法,然后添加数组
*/
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
return advisors;
}
7.1查找所有切面注解方法
因为csdn目录只能支持到六级,所以往下对AspectJ注解处理的部分需要往另一个文章中查看: 查找所有切面注解方法
6.2 查找适合的Advisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//.....略
/**
* 找到合适的增强器
*/
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
/**
* 排序和返回
*/
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
7.1 引界增强和普通Bean增强的处理
protected List<Advisor> findAdvisorsThatCanApply(
List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
try {
//过滤得到对应的Advisor
return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
}
finally {
ProxyCreationContext.setCurrentProxiedBeanName(null);
}
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
//处理引介增强(添加到类方法级别的增强)
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
//略过引介增强,处理普通bean的增强
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
//canApply根据规则判断是否可以作为增强类,不细究了
if (canApply(candidate, clazz, hasIntroductions)) {
eligibleAdvisors.add(candidate);
}
}
return eligibleAdvisors;
}
6.3 排序返回
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//..................略
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
5.3 创建Proxy
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//.............略
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//拿到所有的advisors之后要进行代理的创建了
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
6.1 代理创建和代理实现
直接查看另一篇博客:代理创建和代理实现