1. 测试方法
通知类:
public class LogMethodBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("this is logMethodBeforeAdvice!"); } } public class Log2MethodBeforeAdvice implements MethodBeforeAdvice { @Override public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("xxxxxxxxxxxxxxxxx"); } }
目标接口以及目标类:
public interface IAccount { String say(@NotNull Integer id, @NotNull String desc); String run(); //接口内部定义了hashCode方法 int hashCode(); } public class AccountImpl implements IAccount { @Override public String say(@NotNull Integer id, @NotNull String desc) { return "my "+id + ":" + desc; } @Override public String run() { return "I am runner"; } //继承的是IAccount的hashCode方法 @Override public int hashCode() { return 123; } //继承的是Object的equals方法 @Override public boolean equals(Object obj) { return super.equals(obj); } }
测试方法:
@Configuration public class DefaultAdvisorAutoProxyCreatorConfig { //目标类 @Bean public IAccount accountImpl(){ return new AccountImpl(); } //切面类 @Bean public Log2MethodBeforeAdvice log2(){ return new Log2MethodBeforeAdvice(); } //声明自动代理器 @Bean public DefaultAdvisorAutoProxyCreator defaultAdvisorAutoProxyCreator() { return new DefaultAdvisorAutoProxyCreator(); } //声明Advisor @Bean public NameMatchMethodPointcutAdvisor nameMatchMethodPointcutAdvisor() { NameMatchMethodPointcutAdvisor nameAdvisor = new NameMatchMethodPointcutAdvisor(); //拦截方法 nameAdvisor.addMethodName("*say"); nameAdvisor.setAdvice(new LogMethodBeforeAdvice()); return nameAdvisor; } }
2. 类结构
DefaultAdvisorAutoProxyCreator
是AbstractAdvisorAutoProxyCreator
的子类,由下面方法可知,实现了isEligibleAdvisorBean
方法。
AbstractAdvisorAutoProxyCreator
类是AbstractAutoProxyCreator
的子类,由下面方法可知,实现了getAdvicesAndAdvisorsForBean()
和advisorsPreFiltered()
方法。
- getAdvicesAndAdvisorsForBean()方法:获取该bean对象上所有的Advisor对象(实现自动代理的核心方法);
-
advisorsPreFiltered():默认返回
true
,是着ProxyFactory
代理配置;
AbstractAutoProxyCreator
是模板类,即Spring
完成自动代理的模板方法,定义了算法骨干。子类实现其定义的钩子方法,完成bean
的自动代理。
3. 源码分析
3.1 Spring的自动加载流程
调用如下方法:getBean()
获取单例池中的bean对象。而bean被初始化时,就会被自动
代理。
public class TestSpringProxy { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(DefaultAdvisorAutoProxyCreatorConfig.class); //可以使用@Primary指定元素,或直接使用name名获取。 IAccount bean = (IAccount)applicationContext.getBean("accountImpl"); bean.say(100,"工作"); System.out.println(bean.getClass()); } }
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { //前置处理,未进行代理 @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { return bean; } }
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { @Override public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { if (bean != null) { //获取cacheKey的(对FactoryBean进行处理,加入了&) Object cacheKey = getCacheKey(bean.getClass(), beanName); //判断是否被循环依赖时早期加载 if (this.earlyProxyReferences.remove(cacheKey) != bean) { //包装Bean对象(自动代理) return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; } }
3.2 创建代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { private final Set<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16)); private final Map<Object, Boolean> advisedBeans = new ConcurrentHashMap<>(256); //包装bean对象 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //若bean已经在targetSourcedBeans集合中,说明已经被代理过,直接返回即可。 //`postProcessBeforeInstantiation()`中成功创建的代理对象会将beanName加入到`targetSourceBeans`中。 if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) { return bean; } //若该Bean是基础框架或者免代理的Bean,也不进行处理。 if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) { return bean; } //若`Pointcut`、`Advice`、`Advisor`、`AopInfrastructureBean`也不会进行代理,并且加入到advisedBeans集合中。 //或者判断是否跳过(shouldSkip也是一个钩子方法) if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) { this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } // (重要方法)获取bean上的advice和advisor对象。(该方法是`AbstractAdvisorAutoProxyCreato`内的方法)。获取合格的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; } this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean; } }
AbstractAutoProxyCreator#shouldSkip
的方法,也是一个钩子方法。AspectJAwareAdvisorAutoProxyCreator
(子类)实现了shouldSkip
方法。
父类中shouldSkip
方法作用是判断该bean是否是beanName.ORIGINAL
的类型,若bean是这种类型,则跳过。
获取bean上的advice和advisor对象。
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator { @Nullable private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper; @Override @Nullable protected Object[] getAdvicesAndAdvisorsForBean( Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) { //获取`合格`的Advisor集合。 List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName); if (advisors.isEmpty()) { return DO_NOT_PROXY; } return advisors.toArray(); } //找到合格的Advisor集合 protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { //获取候选的Advisor集合对象; List<Advisor> candidateAdvisors = findCandidateAdvisors(); //筛选候选的Advisor对象,获取`合格的Advisor`对象集合; List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); //子类实现(扩展Advisors) extendAdvisors(eligibleAdvisors); //Advisor按照Order接口进行排序。 if (!eligibleAdvisors.isEmpty()) { eligibleAdvisors = sortAdvisors(eligibleAdvisors); } //返回该bean上的Advicor对象 return eligibleAdvisors; } //获取`所有候选的Advisor集合`(钩子方法,子类也会实现) protected List<Advisor> findCandidateAdvisors() { Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available"); return this.advisorRetrievalHelper.findAdvisorBeans(); } //获取`合格的Advisor`集合 protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } //钩子方法,未实现。 protected void extendAdvisors(List<Advisor> candidateAdvisors) { } //适配器模式(主要为了实现isEligibleAdvisorBean方法) private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper { public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) { super(beanFactory); } //获取合格的Bean的对象。 @Override protected boolean isEligibleBean(String beanName) { return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName); } } }
获取Spring中所有的Advisor
public class BeanFactoryAdvisorRetrievalHelper { //维护的Advisor缓存(初始时为null) @Nullable private volatile String[] cachedAdvisorBeanNames; public List<Advisor> findAdvisorBeans() { String[] advisorNames = this.cachedAdvisorBeanNames; //初始化时为null if (advisorNames == null) { //从容器中(包含父容器)中获取Advisor类型的Bean对象的名字。【注意是Advisor类型,而非Advice类型】 advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors( this.beanFactory, Advisor.class, true, false); //放入本地缓存中。 this.cachedAdvisorBeanNames = advisorNames; } if (advisorNames.length == 0) { return new ArrayList<>(); } List<Advisor> advisors = new ArrayList<>(); //获取Spring容器中所有的advisors后开始处理。 for (String name : advisorNames) { //判断该Advisor是否是可以自动代理的Advisor(由子类实现判断) if (isEligibleBean(name)) { //若bean正在创建,那么什么都不做。 if (this.beanFactory.isCurrentlyInCreation(name)) { if (logger.isTraceEnabled()) { logger.trace("Skipping currently created advisor '" + name + "'"); } } //bean已经被创建后 else { try { //创建Bean,放入List<Advisor>中。 advisors.add(this.beanFactory.getBean(name, Advisor.class)); } catch (BeanCreationException ex) { ... continue; } throw ex; } } } } return advisors; } //钩子方法(由具体子类实现) protected boolean isEligibleBean(String beanName) { return true; } }
子类的特殊实现:
public class DefaultAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator implements BeanNameAware { private boolean usePrefix = false; @Nullable private String advisorBeanNamePrefix; @Override protected boolean isEligibleAdvisorBean(String beanName) { //usePrefix boolean类型,默认false if (!isUsePrefix()) { return true; } String prefix = getAdvisorBeanNamePrefix(); return (prefix != null && beanName.startsWith(prefix)); } }
获取bean上的Advisor
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator { //遭到Bean上合格的Advisor protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { //将beanName放入到`currentProxiedBeanName`中,以便可以在ThreadLocal中获取。 ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //candidateAdvisors:Spring容器中所有的advisor对象; //beanClass:Bean对象类型; return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } } }
AopUtils的工具方法:\
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) { //若是传入的容器内Advisor为空,直接返回 if (candidateAdvisors.isEmpty()) { return candidateAdvisors; } List<Advisor> eligibleAdvisors = new ArrayList<>(); //bean匹配`引介通知`。 for (Advisor candidate : candidateAdvisors) { //判断是否是引介通知(引介通知只有ClassFilter),且匹配 if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) { eligibleAdvisors.add(candidate); } } //判断是否存在`合格的引介通知` boolean hasIntroductions = !eligibleAdvisors.isEmpty(); //匹配普通通知 for (Advisor candidate : candidateAdvisors) { if (candidate instanceof IntroductionAdvisor) { continue; } //查看是否匹配(普通通知) if (canApply(candidate, clazz, hasIntroductions)) { eligibleAdvisors.add(candidate); } } return eligibleAdvisors; }
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) { if (advisor instanceof IntroductionAdvisor) { return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass); } else if (advisor instanceof PointcutAdvisor) { PointcutAdvisor pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { // It doesn't have a pointcut so we assume it applies. return true; } }
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { Assert.notNull(pc, "Pointcut must not be null"); //切点的classFilter是否匹配 if (!pc.getClassFilter().matches(targetClass)) { return false; } //获取切点的methodMatcher MethodMatcher methodMatcher = pc.getMethodMatcher(); //若是方法匹配的值为MethodMatcher.TRUE,则拦截所有的方法 if (methodMatcher == MethodMatcher.TRUE) { return true; } IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<>(); //若不是JDK代理 if (!Proxy.isProxyClass(targetClass)) { //获取目标类对象 classes.add(ClassUtils.getUserClass(targetClass)); } //获取对象的接口 classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); for (Class<?> clazz : classes) { //获取类上所有的方法(包含私有方法) Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz); for (Method method : methods) { //所有的方法进行匹配(包含私有方法),若有一个匹配,那么返回true。 if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false; }
创建代理对象
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware { protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { if (StringUtils.hasLength(beanName) && 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; } //此时我们在这(获取到该Bean上的所有Advisor对象) Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); if (specificInterceptors != DO_NOT_PROXY) { //将该Bean放入到advisedBeans集合中。 this.advisedBeans.put(cacheKey, Boolean.TRUE); //在SingletonTargetSource获取targetSource。 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; } //创建代理对象 protected Object createProxy(Class<?> beanClass, @Nullable String beanName, @Nullable Object[] specificInterceptors, TargetSource targetSource) { if (this.beanFactory instanceof ConfigurableListableBeanFactory) { AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass); } //使用ProxyFactory获取Proxy对象。 ProxyFactory proxyFactory = new ProxyFactory(); //复制ProxyConfig配置属性。 proxyFactory.copyFrom(this); //若proxyTargetClass=false,则为JDK代理; //若proxyTargetClass=true,则为CGLIB代理 if (!proxyFactory.isProxyTargetClass()) { //判断是否应该使用targetClass类而不是接口进行代理。 if (shouldProxyTargetClass(beanClass, beanName)) { proxyFactory.setProxyTargetClass(true); } else { //把这个类实现的接口们,放入到ProxyFactory中。 evaluateProxyInterfaces(beanClass, proxyFactory); } } //处理Advisor对象 Advisor[] advisors = buildAdvisors(beanName, specificInterceptors); proxyFactory.addAdvisors(advisors); proxyFactory.setTargetSource(targetSource); //子类定制proxyFactory对象 customizeProxyFactory(proxyFactory); proxyFactory.setFrozen(this.freezeProxy); // 注意此处。 if (advisorsPreFiltered()) { proxyFactory.setPreFiltered(true); } //创建代理对象。 return proxyFactory.getProxy(getProxyClassLoader()); } //specificInterceptors:该Bean上所有的Advisor。 protected Advisor[] buildAdvisors(@Nullable String beanName, @Nullable Object[] specificInterceptors) { 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++) { advisors[i] = this.advisorAdapterRegistry.wrap(allInterceptors.get(i)); } return advisors; } //处理拦截器Name,去容器内找出来 private Advisor[] resolveInterceptorNames() { BeanFactory bf = this.beanFactory; ConfigurableBeanFactory cbf = (bf instanceof ConfigurableBeanFactory ? (ConfigurableBeanFactory) bf : null); List<Advisor> advisors = new ArrayList<>(); for (String beanName : this.interceptorNames) { //若工厂不是ConfigurableBeanFactory 或者该Bean不在创建中 if (cbf == null || !cbf.isCurrentlyInCreation(beanName)) { Assert.state(bf != null, "BeanFactory required for resolving interceptor names"); //拿到这个Bean,将其包装为Advisor。 Object next = bf.getBean(beanName); advisors.add(this.advisorAdapterRegistry.wrap(next)); } } return advisors.toArray(new Advisor[0]); } }
上述的buildAdvisors()
方法中存在resolveInterceptorNames()
方法,实际上是处理数组interceptorNames
中的beanName,将其在Spring单例池中获取到,并且加入到advisors
中。
当然需要依赖applyCommonInterceptorsFirst
参数的值来决定拦截器的顺序。
需要注意的是:是否创建代理对象由pointcut
来决定。而创建出代理对象执行方法时,该方法会选择合适和Advisor
进行织入。而Bean会保存所有相关的Advisor
。
执行代理方法
为每个方法生成过滤链:依旧依赖的是pointcut
的ClassFilter
和MethodMatcher
对Advice的过滤。
依赖的是NameMatchMethodPointcut
对名字的过滤:
public class NameMatchMethodPointcut extends StaticMethodMatcherPointcut implements Serializable { private List<String> mappedNames = new ArrayList<>(); @Override public boolean matches(Method method, Class<?> targetClass) { //mappedNames为传入的名字匹配模式 for (String mappedName : this.mappedNames) { //判断是否匹配 if (mappedName.equals(method.getName()) || isMatch(method.getName(), mappedName)) { return true; } } return false; } }
若是符合条件,那么该方法上会生成过滤器链。
为什么
AbstractAdvisorAutoProxyCreator
要实现这个advisorsPreFiltered()
这个方法?
- 创建代理流程:找到该Bean对象上所有的Advisor时,使用了Advisor中Pointcut的
类过滤
和方法过滤
。 - 使用代理对象:需要为每个方法创建
AdvisorChain
,而Bean
对象已经在创建代理流程
中使用了类过滤
,那么创建AdvisorChain
无需在进行类过滤
。
如上图所示,该属性使用的场景均是获取方法的AdvisorChain时
进行ClassFilter
过滤的场景。
推荐阅读
https://blog.csdn.net/f641385712/article/details/88904983