Spring扩展点之Aware接口族

2022-10-15,,,

引言

spring中提供了各种aware接口,方便从上下文中获取当前的运行环境,比较常见的几个子接口有:beanfactoryaware,beannameaware,applicationcontextaware,environmentaware,beanclassloaderaware等,这些aware的作用都可以从命名得知

aware处理

其中beannameawarebeanclassloaderawarebeanfactoryaware这三个是直接在bean的初始化之前就处理了的,具体代码在abstractautowirecapablebeanfactory.initializebean方法中:

protected object initializebean(string beanname, object bean, rootbeandefinition mbd) {
    // 判断对象实现的接口类型,处理特定的三种接口类型:beannameaware、beanclassloaderaware和beanfactoryaware。
    if (bean instanceof beannameaware) {
        ((beannameaware) bean).setbeanname(beanname);
    }
 
    if (bean instanceof beanclassloaderaware) {
        ((beanclassloaderaware) bean).setbeanclassloader(getbeanclassloader());
    }
 
    if (bean instanceof beanfactoryaware) {
        ((beanfactoryaware) bean).setbeanfactory(this);
    }
    // 开始bean初始化前处理、初始化、初始化后处理
    object wrappedbean = bean;
    if (mbd == null || !mbd.issynthetic()) {
        wrappedbean = applybeanpostprocessorsbeforeinitialization(wrappedbean, beanname);
    }
 
    try {
        invokeinitmethods(beanname, wrappedbean, mbd);
    }
    catch (throwable ex) {
        throw new beancreationexception(
                (mbd != null ? mbd.getresourcedescription() : null),
                beanname, "invocation of init method failed", ex);
    }
 
    if (mbd == null || !mbd.issynthetic()) {
        wrappedbean = applybeanpostprocessorsafterinitialization(wrappedbean, beanname);
    }
    return wrappedbean;
}

除了这三种之外的那些aware接口的实现就不太一样了,它们都是利用beanpostprocessor接口完成的,关于beanpostprocessor接口的原理可以这篇文章:spring扩展点之beanpostprocessor

applicationcontextaware就是利用applicationcontextawareprocessor实现的:

public object postprocessbeforeinitialization(final object bean, string beanname) throws beansexception {
        accesscontrolcontext acc = null;

        if (system.getsecuritymanager() != null &&
                (bean instanceof environmentaware || bean instanceof embeddedvalueresolveraware ||
                        bean instanceof resourceloaderaware || bean instanceof applicationeventpublisheraware ||
                        bean instanceof messagesourceaware || bean instanceof applicationcontextaware)) {
            acc = this.applicationcontext.getbeanfactory().getaccesscontrolcontext();
        }

        if (acc != null) {
            accesscontroller.doprivileged((privilegedaction<object>) () -> {
              //具体实现
                invokeawareinterfaces(bean);
                return null;
            }, acc);
        }
        else {
                      //具体实现
            invokeawareinterfaces(bean);
        }

        return bean;
    }
private void invokeawareinterfaces(object bean) {
        if (bean instanceof aware) {
            if (bean instanceof environmentaware) {
                ((environmentaware) bean).setenvironment(this.applicationcontext.getenvironment());
            }
            if (bean instanceof embeddedvalueresolveraware) {
                ((embeddedvalueresolveraware) bean).setembeddedvalueresolver(this.embeddedvalueresolver);
            }
            if (bean instanceof resourceloaderaware) {
                ((resourceloaderaware) bean).setresourceloader(this.applicationcontext);
            }
            if (bean instanceof applicationeventpublisheraware) {
                ((applicationeventpublisheraware) bean).setapplicationeventpublisher(this.applicationcontext);
            }
            if (bean instanceof messagesourceaware) {
                ((messagesourceaware) bean).setmessagesource(this.applicationcontext);
            }
            if (bean instanceof applicationcontextaware) {
                ((applicationcontextaware) bean).setapplicationcontext(this.applicationcontext);
            }
        }
    }

applicationcontextawareprocessor的注册奥秘在abstractapplicationcontext.preparebeanfactory方法中:

beanfactory.setbeanclassloader(getclassloader());
beanfactory.addpropertyeditorregistrar(new resourceeditorregistrar(this));
 beanfactory.addbeanpostprocessor(new applicationcontextawareprocessor(this)); 
beanfactory.ignoredependencyinterface(resourceloaderaware.class);
beanfactory.ignoredependencyinterface(applicationeventpublisheraware.class);
beanfactory.ignoredependencyinterface(messagesourceaware.class);
beanfactory.ignoredependencyinterface(applicationcontextaware.class);

《Spring扩展点之Aware接口族.doc》

下载本文的Word格式文档,以方便收藏与打印。