代理對象在哪裏創建
先從bean被創建後如何產生代理對象開始,在AbstractAutowireCapableBeanFactory.doCreateBean
初始化bean創建後,並且將依賴注入到bean中,在調用initializeBean 方法對剛剛完成依賴注入bean進行一次"初始化"
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
}
if (mbd == null || !mbd.isSynthetic()) {
//就是在這裏對符合條件bean 轉換成 代理對象 對象 -> AnnotationAwareAspectJAutoProxyCreator
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
AbstractAutoProxyCreator.postProcessAfterInitialization
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
//判斷Class FactoryBean 實現類,修改bean名字 在beanName前面加上&
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
return wrapIfNecessary(bean, beanName, cacheKey); //這裏將會返回代理後的對象
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//targetSourcedBeans 沒有生成代理bean 緩存
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//advisedBeans 也是緩存,返回false 則不會生成代理對象
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//ORIGINAL 後置表明bean 實例不會變,則不會生成代理對象
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//這裏會返回 BeanFactoryTransactionAttributeSourceAdvisor,如果不創建代理對象,這裏就會返回空數組
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE); //緩存已經解析過bean,後面就不用再解析一次class
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[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
//使用Advisor 去處理class 是否需要生成代理對象,如果需要則返回 advisors 不爲空
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//從容器中獲取內置Advisor 使用一個Advisor 生成Advisor 通過代理工廠生成一堆代理對象
//這裏會返回 BeanFactoryTransactionAttributeSourceAdvisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
extendAdvisors(eligibleAdvisors);
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
上面判斷主要做一些檢查,當所有狀態合法後纔會進入getAdvicesAndAdvisorsForBean
返回通過指定bean生成的通知,在通過Advisor數組生成代理對象。這個方法主要邏輯就是通過
BeanFactoryTransactionAttributeSourceAdvisor 工廠內置Advisor解析Class並且生成pointcut 切點。主要實現在AopUtils
/**
* candidateAdvisors 內置Advisor 也就是BeanFactoryTransactionAttributeSourceAdvisor
* 給定Class 找尋可用Advisor
*/
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
// IntroductionAdvisor只能應用於類級別 事務一般定位到Method上,不會使用這種類型Advisor
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {
// already processed
continue;
}
// 這裏會使用candidate 去解析Class 如果需要生成代理方法或者代理對象 將會返回true
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
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
//pointcut 爲 TransactionAttributeSourcePointcut 內部類
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
//方法匹配器,用於解析Method 是否需要生成代理方法
MethodMatcher methodMatcher = pc.getMethodMatcher();
if (methodMatcher == MethodMatcher.TRUE) { //沒有任何邏輯,沒有方法都會生成代理方法
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) { //向上獲取父類class,排除掉代理class
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
for (Method method : methods) {
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) { //最終調用方法匹配器找到適合方法
return true;
}
}
}
return false;
}
本質依然是使用BeanFactoryTransactionAttributeSourceAdvisor 內部對象來匹配Class 或Method,並且生成Advisor。
主要流程使用BeanFactoryTransactionAttributeSourceAdvisor.Pointcut(TransactionAttributeSourcePointcut 抽象類) -> TransactionAttributeSourcePointcut.matches ->AbstractFallbackTransactionAttributeSource.getTransactionAttribute
-> AnnotationTransactionAttributeSource.findTransactionAttribute ->AnnotationTransactionAttributeSource.determineTransactionAttribute -> TransactionAnnotationParser.TransactionAttribute
其中在AnnotationTransactionAttributeSource.determineTransactionAttribute 方法會使用Spring 支持TransactionAnnotationParser 數組去解析method並且返回TransactionAttribute
TransactionAnnotationParser是Spring 事務註解解析器接口在Class、Method 上解析註解並且將聲明註解解析成TransactionAttribute 支持3種實現
- SpringTransactionAnnotationParser Spring自身數據庫事務 解析@Transactional
- Ejb3TransactionAnnotationParser EJB事務 解析 javax.ejb.TransactionAttribute
- JtaTransactionAnnotationParser JTA1.2 事務 解析javax.transaction.Transactional
我們一起看下如何生成代理對象的createProxy
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 proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this);
if (!proxyFactory.isProxyTargetClass()) { // 如果還沒有設置代理目標類這裏在設置一次
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
//這裏返回Advisor 所以仍然是返回BeanFactoryTransactionAttributeSourceAdvisor
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
// 這裏有兩個邏輯,一根據需求創建AopProxy 二 調用getProxy 創建代理對象
return proxyFactory.getProxy(classLoader);
}
調用AopProxy創建代理目標類,根據不同情況初始化不同AopProxy
public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
// GraalVM Native Image 只支持 Dynamic proxy (java.lang.reflect.Proxy)
if (!NativeDetector.inNativeImage() &&
(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
Class<?> targetClass = config.getTargetClass();
if (targetClass == null) {
throw new AopConfigException("TargetSource cannot determine target class: " +
"Either an interface or a target is required for proxy creation.");
}
if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
return new JdkDynamicAopProxy(config);
}
return new ObjenesisCglibAopProxy(config);
}
else {
return new JdkDynamicAopProxy(config);
}
}
/**
* Determine whether the supplied {@link AdvisedSupport} has only the
* {@link org.springframework.aop.SpringProxy} interface specified
* (or no proxy interfaces specified at all).
*/
private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
Class<?>[] ifcs = config.getProxiedInterfaces();
return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
}
}
其中JdkDynamicAopProxy 是通過InvocationHandler 接口實現,ObjenesisCglibAopProxy就是通過Cglib實現,這次只有看下Cglib如何創建動態對象的
public Object getProxy(@Nullable ClassLoader classLoader) {
try {
Class<?> rootClass = this.advised.getTargetClass();
Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
Class<?> proxySuperClass = rootClass;
if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
proxySuperClass = rootClass.getSuperclass();
Class<?>[] additionalInterfaces = rootClass.getInterfaces();
for (Class<?> additionalInterface : additionalInterfaces) {
this.advised.addInterface(additionalInterface);
}
}
// Validate the class, writing log messages as necessary.
validateClassIfNecessary(proxySuperClass, classLoader);
// Configure CGLIB Enhancer...
//Cglib 核心就是通過Enhancer 對象去創建代理
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
//這裏將Spring 內置7MethodInterceptor 實現
Callback[] callbacks = getCallbacks(rootClass);
Class<?>[] types = new Class<?>[callbacks.length];
for (int x = 0; x < types.length; x++) {
types[x] = callbacks[x].getClass();
}
// fixedInterceptorMap only populated at this point, after getCallbacks call above
enhancer.setCallbackFilter(new ProxyCallbackFilter(
this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
enhancer.setCallbackTypes(types);
// Generate the proxy class and create a proxy instance.
return createProxyClassAndInstance(enhancer, callbacks);
}
}
Cglib樣例
編寫一個簡單Demo類,對方法進行前後增強。
public class Demo {
public void call(){
System.out.println("我就是目標類原始方法");
}
}
編寫攔截器
public class CglibMethodInterceptor implements MethodInterceptor {
/**
* 通過在intercept 上重寫方法達到通知增強邏輯
* @param o 代表Cglib 生成的動態代理類 對象本身
* @param method 代理類中被攔截的接口方法 Method 實例
* @param objects 接口方法參數
* @param methodProxy 用於調用父類真正的業務類方法。可以直接調用被代理類接口方法 原始方法
* @return
* @throws Throwable
*/
@Override
public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
System.out.println("invoke before....");
MonitorUtil.start();
Object invoke = methodProxy.invokeSuper(o, objects);
//Object invoke = method.invoke(o,objects); 這樣會導致棧溢出
System.out.println("invoken after");
MonitorUtil.finish();
return invoke;
}
}
最後創建代理對象
@Test
public void cglibTest(){
Enhancer enhancer = new Enhancer();
enhancer.setClassLoader(this.getClass().getClassLoader());
enhancer.setSuperclass(Demo.class);
enhancer.setCallback(new CglibMethodInterceptor());
Demo proxyInst = (Demo) enhancer.create();
proxyInst.call();
}
執行結果
invoke before....
我就是目標類原始方法
invoken after
其實跟JDK動態代理寫法差不多,都是通過在原始方法前後插入代碼,達到增強。CGLIB支持多個MethodInterceptor,組成一個攔截器鏈,按照一定順序執行intercept。這種方法有利於AOP結構和代理業務代碼解耦。
事務如何通過代理來實現的
通過上面一個小例子,我們已經瞭解到實現代理邏輯核心就是getCallbacks(rootClass)
返回攔截器,內置攔截器有7種,事務實現類就是在CglibAopProxy.DynamicAdvisedInterceptor。
private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
private final AdvisedSupport advised;
public DynamicAdvisedInterceptor(AdvisedSupport advised) {
this.advised = advised;
}
@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
Object target = null;
TargetSource targetSource = this.advised.getTargetSource();
try {
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
//這裏會返回TransactionInterceptor 事務執行核心類
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
Object retVal;
// Check whether we only have one InvokerInterceptor: that is,
// no real advice, but just reflective invocation of the target.
if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { //沒有代理攔截器
// We can skip creating a MethodInvocation: just invoke the target directly.
// Note that the final invoker must be an InvokerInterceptor, so we know
// it does nothing but a reflective operation on the target, and no hot
// swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = methodProxy.invoke(target, argsToUse);
}
else {
// We need to create a method invocation... 在這裏執行事務
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
}
retVal = processReturnType(proxy, target, method, retVal); //包裝返回類型
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
這個內部類主要就是兩個核心方法getInterceptorsAndDynamicInterceptionAdvice,從BeanFactoryTransactionAttributeSourceAdvisor.pointcut 返回MethodInterceptor 實現類TransactionInterceptor 並且使用InterceptorAndDynamicMethodMatcher 將返回MethodInterceptor、MethodMatcher 包裝起來,下面會使用到的。
將攔截器執行鏈作爲構造器參數初始化CglibMethodInvocation,調用proceed 執行事務,proceed 會調用父類ReflectiveMethodInvocation.proceed,核心邏輯就在裏面了。
public Object proceed() throws Throwable {
// We start with an index of -1 and increment early.
// currentInterceptorIndex 默認是-1 相等表示攔截器鏈裏面沒有代理方法,直接執行原方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
//從第一個開始執行
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
//dm 就是上面寫到TransactionAnnotationParser
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this); //調用TransactionInterceptor.invoke
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
這裏使用遞歸方式執行調用鏈
TransactionInterceptor 可以說是Spring事務執行器了,它負責執行事務,它自己本身沒有任務事務實現代碼,都是通TransactionManager 事務管理器來實現事務開始、回滾、提交。
直接從TransactionInterceptor.invoke 開始分析
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
//這裏調用父類TransactionAspectSupport.invokeWithinTransaction
return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
@Override
@Nullable
public Object proceedWithInvocation() throws Throwable {
return invocation.proceed();
}
@Override
public Object getTarget() {
return invocation.getThis();
}
@Override
public Object[] getArguments() {
return invocation.getArguments();
}
});
}
invokeWithinTransaction 看方法嗎方法命名就知道幹什麼的,執行事務方法。三個參數
Method 要執行方法,主要是獲取事務註解上屬性
Class 被代理Class,作業跟Method差不多
InvocationCallback 被實現的class,主要用於執行代理方法。要知道Spring AOP是代理chain 方式執行,一個類不單止是被事務代理的,還有會因爲其他業務被代理了,保證代理鏈能全部執行下去。
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();
//TransactionAttribute 是執行事務必須實體 包含很多重要信息 事務隔離級別、事務傳播級別、異常回滾等
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
//獲取TransactionManager 事務管理器,再平常開發中可以存在自己配置事務管理器情況,先讀取@Transactional value 屬性,
//沒有從transactionManagerBeanName 可以從配置文件指定
//最後就是Spring默認事務實現
final TransactionManager tm = determineTransactionManager(txAttr);
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
//這裏是反應式事務 Mongdb NOSQL使用,這裏略過
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
// CallbackPreferringPlatformTransactionManager 是 PlatformTransactionManager 擴展接口提供在執行事務時暴露一個回調方法
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 獲取正在執行的事務狀態或者創建一個事務 TransactionInfo 事務狀態 會記錄事務執行,用於回滾
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
// invocation 就是被實現類,調用原始方法或者代理方法
// 其實這裏就是around advice 環繞通知 前面開啓事務,下面方法負責回滾或提交
retVal = invocation.proceedWithInvocation();
}
catch (Throwable ex) {
// target invocation exception
//處理業務異常,如果異常符合回滾,就會回滾否則就是commit
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
// 在ThreadLocal 清除事務狀態txInfo
//要知道所有事務都通過ThreadLocal 進行傳遞
//在正常或者異常情況下,清除線程綁定事務
cleanupTransactionInfo(txInfo);
}
//處理下返回值,使用了io.vavr.control.Try 來處理,沒用過 略過下面
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//這個說的很明白 處理完返回值後再進行提交事務
commitTransactionAfterReturning(txInfo);
return retVal;
}
else { //這個是CallbackPreferringPlatformTransactionManager 執行事務方式
//跟上面處理差不多就是多了一個execute 方法,在回調函數去執行事務,相當於將事務執行交給調用者去實現
Object result;
final ThrowableHolder throwableHolder = new ThrowableHolder();
// It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
try {
result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
try {
Object retVal = invocation.proceedWithInvocation();
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
return retVal;
}
catch (Throwable ex) {
if (txAttr.rollbackOn(ex)) {
// A RuntimeException: will lead to a rollback.
if (ex instanceof RuntimeException) {
throw (RuntimeException) ex;
}
else {
throw new ThrowableHolderException(ex);
}
}
else {
// A normal return value: will lead to a commit.
throwableHolder.throwable = ex;
return null;
}
}
finally {
cleanupTransactionInfo(txInfo);
}
});
}
catch (ThrowableHolderException ex) {
throw ex.getCause();
}
catch (TransactionSystemException ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
ex2.initApplicationException(throwableHolder.throwable);
}
throw ex2;
}
catch (Throwable ex2) {
if (throwableHolder.throwable != null) {
logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
}
throw ex2;
}
// Check result state: It might indicate a Throwable to rethrow.
if (throwableHolder.throwable != null) {
throw throwableHolder.throwable;
}
return result;
}
}
總結
在這篇文章中我們簡單學習了Spring初始化bean時,如何將bean創建成一個代理對象,並且使用Cglib技術創建一個代理bean,在結合事務管理器分析了代理如何去實現Spring事務的。使用一個小例子演示了Cglib代理如何實現的,方便理解Spring AOP代理是通過一個攔截器去實現的,一個對象的多個代理封裝到調用鏈裏面,執行方法時順序執行,保證每一個代理與代理之間沒有任何聯繫,相互獨立。這次我還了解了Spring代理機制原理,通過Advisor實現類去解析Class、Method,通過PointcutAdvisor(匹配Class、Method)、IntroductionAdvisor (支持Class)是否需要生成代理對象。然後在通過專門代理工程去生成對應代理對象。
我們簡單瞭解事務實現,其實就是環繞通知實現而已,還了解到事務狀態傳遞是通過ThreadLocal來實現的。