最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

spring的TransactionalEventListener事務(wù)感知源碼解析

 更新時(shí)間:2023年09月11日 11:06:00   作者:codecraft  
這篇文章主要為大家介紹了spring的TransactionalEventListener事務(wù)感知源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

本文主要研究一下spring的TransactionalEventListener

TransactionalEventListener

org/springframework/transaction/event/TransactionalEventListener.java

/**
 * An {@link EventListener} that is invoked according to a {@link TransactionPhase}.
 *
 * <p>If the event is not published within an active transaction, the event is discarded
 * unless the {@link #fallbackExecution} flag is explicitly set. If a transaction is
 * running, the event is processed according to its {@code TransactionPhase}.
 *
 * <p>Adding {@link org.springframework.core.annotation.Order @Order} to your annotated
 * method allows you to prioritize that listener amongst other listeners running before
 * or after transaction completion.
 *
 * @author Stephane Nicoll
 * @author Sam Brannen
 * @since 4.2
 */
@Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EventListener
public @interface TransactionalEventListener {
    /**
     * Phase to bind the handling of an event to.
     * <p>The default phase is {@link TransactionPhase#AFTER_COMMIT}.
     * <p>If no transaction is in progress, the event is not processed at
     * all unless {@link #fallbackExecution} has been enabled explicitly.
     */
    TransactionPhase phase() default TransactionPhase.AFTER_COMMIT;
    /**
     * Whether the event should be processed if no transaction is running.
     */
    boolean fallbackExecution() default false;
    /**
     * Alias for {@link #classes}.
     */
    @AliasFor(annotation = EventListener.class, attribute = "classes")
    Class<?>[] value() default {};
    /**
     * The event classes that this listener handles.
     * <p>If this attribute is specified with a single value, the annotated
     * method may optionally accept a single parameter. However, if this
     * attribute is specified with multiple values, the annotated method
     * must <em>not</em> declare any parameters.
     */
    @AliasFor(annotation = EventListener.class, attribute = "classes")
    Class<?>[] classes() default {};
    /**
     * Spring Expression Language (SpEL) attribute used for making the event
     * handling conditional.
     * <p>The default is {@code ""}, meaning the event is always handled.
     * @see EventListener#condition
     */
    String condition() default "";
}
TransactionalEventListener是EventListener的事務(wù)感知版本,默認(rèn)的是TransactionPhase是AFTER_COMMIT

ApplicationListenerMethodTransactionalAdapter

org/springframework/transaction/event/ApplicationListenerMethodTransactionalAdapter.java

/**
 * {@link GenericApplicationListener} adapter that delegates the processing of
 * an event to a {@link TransactionalEventListener} annotated method. Supports
 * the exact same features as any regular {@link EventListener} annotated method
 * but is aware of the transactional context of the event publisher.
 *
 * <p>Processing of {@link TransactionalEventListener} is enabled automatically
 * when Spring's transaction management is enabled. For other cases, registering
 * a bean of type {@link TransactionalEventListenerFactory} is required.
 *
 * @author Stephane Nicoll
 * @author Juergen Hoeller
 * @since 4.2
 * @see ApplicationListenerMethodAdapter
 * @see TransactionalEventListener
 */
class ApplicationListenerMethodTransactionalAdapter extends ApplicationListenerMethodAdapter {
    private final TransactionalEventListener annotation;
    public ApplicationListenerMethodTransactionalAdapter(String beanName, Class<?> targetClass, Method method) {
        super(beanName, targetClass, method);
        TransactionalEventListener ann = AnnotatedElementUtils.findMergedAnnotation(method, TransactionalEventListener.class);
        if (ann == null) {
            throw new IllegalStateException("No TransactionalEventListener annotation found on method: " + method);
        }
        this.annotation = ann;
    }
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (TransactionSynchronizationManager.isSynchronizationActive()
                && TransactionSynchronizationManager.isActualTransactionActive()) {
            TransactionSynchronization transactionSynchronization = createTransactionSynchronization(event);
            TransactionSynchronizationManager.registerSynchronization(transactionSynchronization);
        }
        else if (this.annotation.fallbackExecution()) {
            if (this.annotation.phase() == TransactionPhase.AFTER_ROLLBACK && logger.isWarnEnabled()) {
                logger.warn("Processing " + event + " as a fallback execution on AFTER_ROLLBACK phase");
            }
            processEvent(event);
        }
        else {
            // No transactional event execution at all
            if (logger.isDebugEnabled()) {
                logger.debug("No transaction is active - skipping " + event);
            }
        }
    }
    private TransactionSynchronization createTransactionSynchronization(ApplicationEvent event) {
        return new TransactionSynchronizationEventAdapter(this, event, this.annotation.phase());
    }
    private static class TransactionSynchronizationEventAdapter extends TransactionSynchronizationAdapter {
        private final ApplicationListenerMethodAdapter listener;
        private final ApplicationEvent event;
        private final TransactionPhase phase;
        public TransactionSynchronizationEventAdapter(ApplicationListenerMethodAdapter listener,
                ApplicationEvent event, TransactionPhase phase) {
            this.listener = listener;
            this.event = event;
            this.phase = phase;
        }
        @Override
        public int getOrder() {
            return this.listener.getOrder();
        }
        @Override
        public void beforeCommit(boolean readOnly) {
            if (this.phase == TransactionPhase.BEFORE_COMMIT) {
                processEvent();
            }
        }
        @Override
        public void afterCompletion(int status) {
            if (this.phase == TransactionPhase.AFTER_COMMIT && status == STATUS_COMMITTED) {
                processEvent();
            }
            else if (this.phase == TransactionPhase.AFTER_ROLLBACK && status == STATUS_ROLLED_BACK) {
                processEvent();
            }
            else if (this.phase == TransactionPhase.AFTER_COMPLETION) {
                processEvent();
            }
        }
        protected void processEvent() {
            this.listener.processEvent(this.event);
        }
    }
}
ApplicationListenerMethodTransactionalAdapter繼承了ApplicationListenerMethodAdapter,它的構(gòu)造器會找到指定方法的TransactionalEventListener信息;其onApplicationEvent方法在有事務(wù)的時(shí)候會創(chuàng)建并注冊transactionSynchronization到當(dāng)前事務(wù),沒有事務(wù)若允許fallbackExecution也會執(zhí)行processEvent
TransactionSynchronizationEventAdapter只是覆蓋了beforeCommit及afterCompletion兩個(gè)方法,在afterCompletion方法中根據(jù)status的值與phase的值的匹配關(guān)系決定是否執(zhí)行processEvent

TransactionalEventListenerFactory

org/springframework/transaction/event/TransactionalEventListenerFactory.java

/**
 * {@link EventListenerFactory} implementation that handles {@link TransactionalEventListener}
 * annotated methods.
 *
 * @author Stephane Nicoll
 * @since 4.2
 */
public class TransactionalEventListenerFactory implements EventListenerFactory, Ordered {
    private int order = 50;
    public void setOrder(int order) {
        this.order = order;
    }
    @Override
    public int getOrder() {
        return this.order;
    }
    @Override
    public boolean supportsMethod(Method method) {
        return AnnotatedElementUtils.hasAnnotation(method, TransactionalEventListener.class);
    }
    @Override
    public ApplicationListener<?> createApplicationListener(String beanName, Class<?> type, Method method) {
        return new ApplicationListenerMethodTransactionalAdapter(beanName, type, method);
    }
}
TransactionalEventListenerFactory用于創(chuàng)建ApplicationListenerMethodTransactionalAdapter

EventListenerMethodProcessor

org/springframework/context/event/EventListenerMethodProcessor.java

public class EventListenerMethodProcessor
        implements SmartInitializingSingleton, ApplicationContextAware, BeanFactoryPostProcessor {
    //......
    @Override
    public void afterSingletonsInstantiated() {
        ConfigurableListableBeanFactory beanFactory = this.beanFactory;
        Assert.state(this.beanFactory != null, "No ConfigurableListableBeanFactory set");
        String[] beanNames = beanFactory.getBeanNamesForType(Object.class);
        for (String beanName : beanNames) {
            if (!ScopedProxyUtils.isScopedTarget(beanName)) {
                Class<?> type = null;
                try {
                    type = AutoProxyUtils.determineTargetClass(beanFactory, beanName);
                }
                catch (Throwable ex) {
                    // An unresolvable bean type, probably from a lazy bean - let's ignore it.
                    if (logger.isDebugEnabled()) {
                        logger.debug("Could not resolve target class for bean with name '" + beanName + "'", ex);
                    }
                }
                if (type != null) {
                    if (ScopedObject.class.isAssignableFrom(type)) {
                        try {
                            Class<?> targetClass = AutoProxyUtils.determineTargetClass(
                                    beanFactory, ScopedProxyUtils.getTargetBeanName(beanName));
                            if (targetClass != null) {
                                type = targetClass;
                            }
                        }
                        catch (Throwable ex) {
                            // An invalid scoped proxy arrangement - let's ignore it.
                            if (logger.isDebugEnabled()) {
                                logger.debug("Could not resolve target bean for scoped proxy '" + beanName + "'", ex);
                            }
                        }
                    }
                    try {
                        processBean(beanName, type);
                    }
                    catch (Throwable ex) {
                        throw new BeanInitializationException("Failed to process @EventListener " +
                                "annotation on bean with name '" + beanName + "'", ex);
                    }
                }
            }
        }
    }
    private void processBean(final String beanName, final Class<?> targetType) {
        if (!this.nonAnnotatedClasses.contains(targetType) &&
                AnnotationUtils.isCandidateClass(targetType, EventListener.class) &&
                !isSpringContainerClass(targetType)) {
            Map<Method, EventListener> annotatedMethods = null;
            try {
                annotatedMethods = MethodIntrospector.selectMethods(targetType,
                        (MethodIntrospector.MetadataLookup<EventListener>) method ->
                                AnnotatedElementUtils.findMergedAnnotation(method, EventListener.class));
            }
            catch (Throwable ex) {
                // An unresolvable type in a method signature, probably from a lazy bean - let's ignore it.
                if (logger.isDebugEnabled()) {
                    logger.debug("Could not resolve methods for bean with name '" + beanName + "'", ex);
                }
            }
            if (CollectionUtils.isEmpty(annotatedMethods)) {
                this.nonAnnotatedClasses.add(targetType);
                if (logger.isTraceEnabled()) {
                    logger.trace("No @EventListener annotations found on bean class: " + targetType.getName());
                }
            }
            else {
                // Non-empty set of methods
                ConfigurableApplicationContext context = this.applicationContext;
                Assert.state(context != null, "No ApplicationContext set");
                List<EventListenerFactory> factories = this.eventListenerFactories;
                Assert.state(factories != null, "EventListenerFactory List not initialized");
                for (Method method : annotatedMethods.keySet()) {
                    for (EventListenerFactory factory : factories) {
                        if (factory.supportsMethod(method)) {
                            Method methodToUse = AopUtils.selectInvocableMethod(method, context.getType(beanName));
                            ApplicationListener<?> applicationListener =
                                    factory.createApplicationListener(beanName, targetType, methodToUse);
                            if (applicationListener instanceof ApplicationListenerMethodAdapter) {
                                ((ApplicationListenerMethodAdapter) applicationListener).init(context, this.evaluator);
                            }
                            context.addApplicationListener(applicationListener);
                            break;
                        }
                    }
                }
                if (logger.isDebugEnabled()) {
                    logger.debug(annotatedMethods.size() + " @EventListener methods processed on bean '" +
                            beanName + "': " + annotatedMethods);
                }
            }
        }
    }
    //......
}
EventListenerMethodProcessor實(shí)現(xiàn)了SmartInitializingSingleton接口,其afterSingletonsInstantiated方法先確定type,然后執(zhí)行processBean,該方法會先收集annotatedMethods,然后遍歷該方法,在遍歷factories針對支持該方法的factory執(zhí)行createApplicationListener,添加到context中

小結(jié)

TransactionalEventListener是EventListener的事務(wù)感知版本,默認(rèn)的是TransactionPhase是AFTER_COMMIT,TransactionSynchronizationEventAdapter只是覆蓋了beforeCommit及afterCompletion兩個(gè)方法,在afterCompletion方法中根據(jù)status的值與phase的值的匹配關(guān)系決定是否執(zhí)行processEvent,因而這里拋出的異常會被捕獲并log下來

doc

以上就是spring的TransactionalEventListener源碼解析的詳細(xì)內(nèi)容,更多關(guān)于spring TransactionalEventListener的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java實(shí)現(xiàn)經(jīng)典角色扮演偵探游戲游戲的示例代碼

    Java實(shí)現(xiàn)經(jīng)典角色扮演偵探游戲游戲的示例代碼

    這篇文章主要介紹了如何利用Java語言自制一個(gè)偵探文字游戲—《角色扮演偵探》,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編學(xué)習(xí)一下
    2022-02-02
  • SpringMVC中的SimpleUrlHandlerMapping用法詳解

    SpringMVC中的SimpleUrlHandlerMapping用法詳解

    這篇文章主要介紹了SpringMVC中的SimpleUrlHandlerMapping用法詳解,SimpleUrlHandlerMapping是Spring MVC中適用性最強(qiáng)的Handler Mapping類,允許明確指定URL模式和Handler的映射關(guān)系,有兩種方式聲明SimpleUrlHandlerMapping,需要的朋友可以參考下
    2023-10-10
  • 解決java中的父類私有成員變量的繼承問題

    解決java中的父類私有成員變量的繼承問題

    這篇文章主要介紹了解決java中的父類私有成員變量的繼承問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • Java?Lombok實(shí)現(xiàn)手機(jī)號碼校驗(yàn)的示例代碼

    Java?Lombok實(shí)現(xiàn)手機(jī)號碼校驗(yàn)的示例代碼

    手機(jī)號碼校驗(yàn)通常是系統(tǒng)開發(fā)中最基礎(chǔ)的功能之一,本文主要介紹了Java?Lombok實(shí)現(xiàn)手機(jī)號碼校驗(yàn)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • 詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier

    詳解Java并發(fā)工具類之CountDownLatch和CyclicBarrier

    在JDK的并發(fā)包中,有幾個(gè)非常有用的并發(fā)工具類,它們分別是:CountDownLatch、CyclicBarrier、Semaphore和Exchanger,本文主要來講講其中CountDownLatch和CyclicBarrier的使用,感興趣的可以了解一下
    2023-06-06
  • JAVA比較兩張圖片相似度的方法

    JAVA比較兩張圖片相似度的方法

    這篇文章主要介紹了JAVA比較兩張圖片相似度的方法,涉及java針對圖片像素操作的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-07-07
  • Java中OGNL表達(dá)式語言的使用詳解

    Java中OGNL表達(dá)式語言的使用詳解

    本文介紹了OGNL(ObjectGraphNavigationLanguage)表達(dá)式語言,這是一種用于Java語言的對象圖導(dǎo)航和操作的表達(dá)式語言,它支持訪問對象屬性、調(diào)用對象方法、執(zhí)行算術(shù)和邏輯運(yùn)算,以及處理集合和數(shù)組等操作,OGNL的語法簡潔明了
    2024-12-12
  • 圖文詳解JAVA實(shí)現(xiàn)快速排序

    圖文詳解JAVA實(shí)現(xiàn)快速排序

    這篇文章主要給大家介紹了關(guān)于JAVA實(shí)現(xiàn)快速排序的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • java并發(fā)高的情況下用ThreadLocalRandom來生成隨機(jī)數(shù)

    java并發(fā)高的情況下用ThreadLocalRandom來生成隨機(jī)數(shù)

    如果我們想要生成一個(gè)隨機(jī)數(shù),通常會使用Random類。但是在并發(fā)情況下Random生成隨機(jī)數(shù)的性能并不是很理想,本文主要介紹了java并發(fā)高的情況下用ThreadLocalRandom來生成隨機(jī)數(shù),感興趣的可以了解一下
    2022-05-05
  • 詳解Java并發(fā)之Condition

    詳解Java并發(fā)之Condition

    這篇文章主要介紹了Java并發(fā)編程之Condition,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-06-06

最新評論

桦南县| 久治县| 丽江市| 图木舒克市| 磐安县| 敦煌市| 蒙山县| 云安县| 茶陵县| 子长县| 宜兰县| 会同县| 苗栗县| 奈曼旗| 玉环县| 松江区| 凌源市| 开化县| 高邑县| 行唐县| 定兴县| 辉南县| 澜沧| 嘉荫县| 原阳县| 府谷县| 观塘区| 察雅县| 通江县| 鲁山县| 东乌| 波密县| 临安市| 朝阳区| 南漳县| 和田县| 南康市| 英吉沙县| 乐都县| 墨江| 陆河县|