系列文章目录
切点匹配解析
Advisor与@Aspect解析
getPointcut解析
Advisor解析
文章目录
前言
SpringAOP是通过调用AnnotationAwareAspectJAutoProxyCreator类创建creator对象从而开始AOP功能,而具体执行的方法则是通过wrapIfNecessary()方法对目标类进行切面创建、代理生成等功能
// 实例化creator
AnnotationAwareAspectJAutoProxyCreator creator = new AnnotationAwareAspectJAutoProxyCreator();
// 初始化bean工厂
creator.initBeanFactory(beanFactory);
// 创建代理过程
Object o1 = creator.wrapIfNecessary(new Target1(), "target1", "target1");
((Target1) o1).foo();
一、模拟AnnotationAwareAspectJAutoProxyCreator
创建模拟的AnnotationAwareAspectJAutoProxyCreator类仍与AnnotationAwareAspectJAutoProxyCreator类一样扩展了AspectJAwareAdvisorAutoProxyCreator类
SimulateAnnotationAwareAspectJAutoProxyCreator类实际是通过initBeanFactory()方法进行初始化传入参数为ConfigurableListableBeanFactory类的beanFactory
initBeanFactory功能:
1.实例化SimulateAbstractAspectJAdvisorFactoryImpl对象作为aspectJAdvisorFactory(模拟AbstractAspectJAdvisorFactory)
2.BeanFactoryAspectJAdvisorsBuilderAdapter封装传入的beanFactory与1中实例化的aspectJAdvisorFactory
public class SimulateAnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
@Nullable
private AspectJAdvisorFactory aspectJAdvisorFactory;
@Nullable
private SimulateBeanFactoryAspectJAdvisorsBuilder aspectJAdvisorsBuilder;
public SimulateAnnotationAwareAspectJAutoProxyCreator() {
}
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.initBeanFactory(beanFactory);
if (this.aspectJAdvisorFactory == null) {
// this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
this.aspectJAdvisorFactory = new SimulateAbstractAspectJAdvisorFactoryImpl();
}
this.aspectJAdvisorsBuilder = new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}
}
BeanFactoryAspectJAdvisorsBuilderAdapter
BeanFactoryAspectJAdvisorsBuilderAdapter方法继承SimulateBeanFactoryAspectJAdvisorsBuilder(该方法也是模拟方法),从构造函数中可以得知其是通过父类的构造方法进行实例化即SimulateBeanFactoryAspectJAdvisorsBuilder()中进行实例化
private class BeanFactoryAspectJAdvisorsBuilderAdapter extends SimulateBeanFactoryAspectJAdvisorsBuilder {
public BeanFactoryAspectJAdvisorsBuilderAdapter(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
super(beanFactory, advisorFactory);
}
protected boolean isEligibleBean(String beanName) {
return SimulateAnnotationAwareAspectJAutoProxyCreator.this.isEligibleAspectBean(beanName);
}
}
SimulateBeanFactoryAspectJAdvisorsBuilder
SimulateBeanFactoryAspectJAdvisorsBuilder中构造方法即单独封装了beanFactory与advisorFactory两个工厂对象(后续切面获取时会用到)
public class SimulateBeanFactoryAspectJAdvisorsBuilder {
private ListableBeanFactory beanFactory;
private AspectJAdvisorFactory advisorFactory;
public SimulateBeanFactoryAspectJAdvisorsBuilder(ListableBeanFactory beanFactory, AspectJAdvisorFactory advisorFactory) {
this.beanFactory = beanFactory;
this.advisorFactory = advisorFactory;
}
}
initBeanFactory传入spring的beanFactory同时内部实例化advisorFactory,然后将两个工厂通过BeanFactoryAspectJAdvisorsBuilderAdapter进行封装
二、wrapIfNecessary()
wrapIfNecessary核心功能:
1.获取当前bean匹配的切面集合
2.为当前bean创建代理
@Override
public Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){
// 找到和当前bean匹配的advisor
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
// 创建代理
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}
切面获取与匹配
根据方法名得知该方法是获取当前bean切面对象
给定当前bean类型与bean名称通过findEligibleAdvisors()获取切面对象集合并返回
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = this.findEligibleAdvisors(beanClass, beanName);
return advisors.isEmpty() ? DO_NOT_PROXY : advisors.toArray();
}
findEligibleAdvisors中通过findCandidateAdvisors()方法获取所有候选的advisor对象(解析获取advisor) 然后通过findAdvisorsThatCanApply()方法确定能够匹配当前bean方法的advisor集合并返回
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 获取候选Advisors对象(解析advisors实例)
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
// 从所有advisor中,筛选出跟当前bean匹配的advisor
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
this.extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
切面获取:findCandidateAdvisors()
通过aspectJAdvisorsBuilder.buildAspectJAdvisors()方法进行切面集合获取
同时可以发现buildAspectJAdvisors()是调用内部类aspectJAdvisorsBuilder中的方法
// 获取advisor切面对象
protected List<Advisor> findCandidateAdvisors() {
//找到继承 Advisor 的 advisor
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {
//通过解析切面获取 advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
即buildAspectJAdvisors是aspectJAdvisorsBuilder内部类中的方法,且因为内部类中封装了beanFactory与advisorFactory对象,在进行切面获取时可以直接调用
public List<Advisor> buildAspectJAdvisors() {
// 获取所有Object类型 bean名称
String[] strings1 = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);
List<Advisor> advisors = new ArrayList<>();
for (String beanName : strings1) {
Class<?> beanType = this.beanFactory.getType(beanName);
// 通过advisor工厂验证当前类型是否为@Aspect类型切面
if (this.advisorFactory.isAspect(beanType)) {
AspectMetadata aspectMetadata = new AspectMetadata(beanType, beanName);
// 目前仅考虑单例解析
// BeanFactoryAspectInstanceFactory是一个MetadataFactory
BeanFactoryAspectInstanceFactory factory = new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (classAdvisors != null){
advisors.addAll(classAdvisors);
}
}
}
return advisors;
}
具体切面获取的解析过程Advisor获取解析
切面匹配:findAdvisorsThatCanApply()
主要通过AopUtils.findAdvisorsThatCanApply()方法进行匹配,具体过程可以查看切面配对解析
protected List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
ProxyCreationContext.setCurrentProxiedBeanName(beanName);
List var4;
try {
var4 = AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
} finally {
ProxyCreationContext.setCurrentProxiedBeanName((String)null);
}
return var4;
}
代理创建
代理创建主要通过当前creator中的createProxy()方法进行创建,具体过程可以参考JDK代理创建
@Override
public Object wrapIfNecessary(Object bean, String beanName, Object cacheKey){
// 找到和当前bean匹配的advisor
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
// 创建代理
Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
return proxy;
}