Spring自动装配组件之Aware

68 阅读2分钟

Spring自动装配组件之Aware

前言

自定义组件使用Spring底层的组件(ApplicationContext)需要实现对应的Aware接口,在创建对象时对调用相关方法,以方法回调的方式将相关组件注入到自定义组件中。

Spring 对此提供了一些接口 如 Aware

Aware接口

在这里插入图片描述
我们来挑几个常用Aware 子接口

ApplicationContextAware ioc容器组件

BeanNameAware bean 名字组件

EmbeddedValueResolverAware 字符串解析器组件

自定义一些组件想要使用Spring 一些功能 ,可以实现 xxxAware 接口,在创建对象的时候会自动调用接口规定的方法注入相关的组件。

废话不多说,上代码

新建 AwareTest类来实现这几个接口

@Component
public class AwareTest implements ApplicationContextAware, BeanNameAware, EmbeddedValueResolverAware {


    private ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContexts) throws BeansException {
        applicationContext = applicationContexts;
        System.out.println("  applicationContext = " + applicationContext);
    }

    @Override
    public void setBeanName(String s) {
        System.out.println("bean name is  =  " + s);
    }


    /**
     * 对外提供获取bean 方法
     * @param beanName
     * @param <T>
     * @return
     */
    public  <T> T getObject(String beanName) {
        return (T) applicationContext.getBean(beanName);
    }


     //根据类型获取
    public  <T> T getObject(Class classz) {
        return (T) applicationContext.getBean(classz);
    }

    /**
     * 字符串解析器
     * @param stringValueResolver
     */
    @Override
    public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
        System.out.println(stringValueResolver.resolveStringValue("你好 ${os.name} 18*20 = #{18*20}"));
    }
}

测试

   @Test
    public void test3(){

        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AwareTest.class);
        System.out.println("test 中的----  applicationContext  " +  applicationContext );

        AwareTest bean = applicationContext.getBean(AwareTest.class);
        System.out.println(" bean  =  " +  bean);
        Object awareTest = bean.getObject("awareTest");
        System.out.println(" awareTest  =  " +  awareTest);


    }

可以看到 AwareTest 类现在可以从中具有ioc的功能,字符解析器可以对指定字符进行解析。

bean name is = awareTest
你好 Windows 7 18*20 = 360
applicationContext = org.springframework.context.annotation.AnnotationConfigApplicationContext@5aa6202e: startup date [Sun May 03 18:11:35 CST 2020]; root of context hierarchy
test 中的---- applicationContext org.springframework.context.annotation.AnnotationConfigApplicationContext@5aa6202e: startup date [Sun May 03 18:11:35 CST 2020]; root of context hierarchy
bean = com.example.springdemo.aware.AwareTest@6826c41e
awareTest = com.example.springdemo.aware.AwareTest@6826c41e

Aware 接口 原理

我们知道要想给Spring bean进行包装,在bean初始化前后的时候给bean额外添加一些功能,比如添加指定的组件等,而恰巧的是Spring 中提供了 BeanPostProcessor接口后置处理器。

在这里插入图片描述
Aware 子接口 xxxxAware 对应的处理器

//没有用pulic 没有对外使用,让其实现xxxxAware 接口扩展使用 符合
class ApplicationContextAwareProcessor implements BeanPostProcessor {
    private final ConfigurableApplicationContext applicationContext;
    private final StringValueResolver embeddedValueResolver;

    public ApplicationContextAwareProcessor(ConfigurableApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
        this.embeddedValueResolver = new EmbeddedValueResolver(applicationContext.getBeanFactory());
    }
//在bean初始化之前对bean 设置一些组件
    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(new PrivilegedAction<Object>() {
                public Object run() {
                        //设置属性ApplicationContextAwareProcessor.this.invokeAwareInterfaces(bean);
                    return null;
                }
            }, acc);
        } else {
        //设置属性
            this.invokeAwareInterfaces(bean);
        }

        return bean;
    }

//判断此bean是否实现了aware接口  然后在对具体的接口进行判断,导入相应的组件
    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) {
//导入ioc容器组件                ((ApplicationContextAware)bean).setApplicationContext(this.applicationContext);
            }
        }

    }
//初始化之后直接返回
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        return bean;
    }
}