咱们先说如果该办法是public,钻研一下其中的细节
@Servicepublic class TestServiceImpl { @Transactional(rollbackFor = Exception.class) public void trans1(){}}
AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(),其中applyBeanPostProcessorsAfterInitialization()继承自AbstractAutoProxyCreator,上面是办法细节
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; //getBeanPostProcessors()是sptring boot启动时系统配置的BeanPostProcessor;其中有一个BeanPostProcessor叫做AnnotationAwareAspectJAutoProxyCreator; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { //当遍历AnnotationAwareAspectJAutoProxyCreator时,执行其postProcessAfterInitialization() Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
以下是AbstractAutoProxyCreator.postProcessAfterInitialization()细节:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException { if (bean != null) { Object cacheKey = getCacheKey(bean.getClass(), beanName); if (!this.earlyProxyReferences.contains(cacheKey)) { //这个办法的重要逻辑是,依据beanName获取告诉列表,如果列表不为空,创立代理类; return wrapIfNecessary(bean, beanName, cacheKey); } } return bean; }
图2
图3
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { //获取bean和beanName获取告诉列表. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); //本示例中testServiceImpl的specificInterceptors如图2所示; //如果告诉列表不为空,则创立代理类 if (specificInterceptors != DO_NOT_PROXY) { this.advisedBeans.put(cacheKey, Boolean.TRUE); //执行具体创立代理逻辑,本示例中testServiceImpl的specificInterceptors如图3所示 Object proxy = createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)); this.proxyTypes.put(cacheKey, proxy.getClass()); //间接返回 return proxy; } //如果没有匹配的告诉列表,返回一般的bean this.advisedBeans.put(cacheKey, Boolean.FALSE); return bean;}
如果咱们测试用例中的 public 去掉呢?,咱们间接贴出后果:
图4
能够看到 specificInterceptors = null,也就是说并没有为其生成代理类。什么起因呢?咱们持续往下看:
//candidateAdvisors来自spring boot启动是配置的告诉列表 protected List<Advisor> findAdvisorsThatCanApply( List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) { ProxyCreationContext.setCurrentProxiedBeanName(beanName); try { //由AopUtils.findAdvisorsThatCanApply()执行具体的匹配逻辑 return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); } finally { ProxyCreationContext.setCurrentProxiedBeanName(null); } }
咱们能够看到候选的告诉列表有24个
图5
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) { IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; } Set<Class<?>> classes = new LinkedHashSet<>(); 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) { //因为introductionAwareMethodMatcher == null,所以methodMatcher.matches理论执行咱们的候选告诉器match办法; if (introductionAwareMethodMatcher != null ? introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) : methodMatcher.matches(method, targetClass)) { return true; } } } return false;}
图6
以TransactionAttributeSourcePointcut.matches()为例:
图7
public boolean matches(Method method, @Nullable Class<?> targetClass) { if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) { return false; } //图7为tas实例 TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); }
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { // We need to work it out. TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);}
tas.getTransactionAttribute()会调用AbstractFallbackTransactionAttributeSource.computeTransactionAttribute():
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) { // Don't allow no-public methods as required. //通过下面这个正文看出不容许非public,因而返回 null; if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { return null; }}
此时下面的matches()返回false,最终AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)返回空列表,这样一来AbstractAutoProxyCreator.wrapIfNecessary()中的 specificInterceptors 变量为null,也就没有方法创立代理类了!
最初,再抛出一个问题,如果一个service @Transactional办法既有 public,又有 no-pubic 会怎么呢?欢送一起探讨~~~