美文网首页开源框架-Spring系列Spring
[Spring]Spring的Aware接口-装配

[Spring]Spring的Aware接口-装配

作者: AbstractCulture | 来源:发表于2021-01-10 17:20 被阅读0次

    Aware

    Aware:察觉的、意识到的。
    英文示例: She was not aware of having done wrong. 她沒有意識到做錯了事。
    Spring提供了一系列扩展自顶层接口Aware的接口。开发者实现了该类接口后,可以在接口提供的方法中访问Spring的资源。简单的说,就是实现了该接口,就等于拿到了容器的钥匙。
    Spring框架会察觉实现了这类接口的Bean,然后将容器资源传递到方法参数中提供给开发者进行扩展,所以实现了该接口的同时,需要做好信息同步,否则其他开发者会感到诧异-为什么我的Bean发生了别的行为?。

    public interface Aware {
    
    }
    

    UML

    UML
    • ApplicationContextAware: 访问容器上下文本身,即ApplicationContext.
    • BeanNameAware: 访问BeanName.比如说,一个userService,你想知道它在运行时期的BeanName,可以通过这个方式访问。
    • MessageSourceAware: 访问容器中的MessageSource.
    • EnvironmentAware: 访问容器中的Environment,可以设置当前component的环境变量.
    • ApplicationEventPublisherAware: 访问该对象在容器中的事件推送者对象。
    • BeanFactoryAware: 访问BeanFactory.在填充常规bean属性之后的初始化回调(例如InitializingBean.afterPropertiesSet()或自定义init-method)之前调用.
    • ResourceLoaderAware: 可以获取容器加载资源的ResourceLoader.不同容器可能会用不同的ResourceLoader.所以使用的时候最好用instanceof来判断一下。

    此处列举的只是常见的Aware接口,还有很多Aware接口,例如:BookstrapContextAwareLoadTimeWeaverAwareNotificationPublishAwarePortletConfigAwareServletConfigAware等等。读者可以自行进行扩展阅读.

    Aware

    Code示例

    由于接口过多,此处仅演示BeanNameAwareApplicationContextAware

    通过实现ApplicationContextAware编写一个简易的SpringContextUtil

    在开发的过程中,往往需要将一些常用的操作写成工具类,比如Redis、RabbitMQ、Http等。
    如果需要用到Spring的Bean,诸如:RedisTemplate、RabbitMQTemplate、RestTemplate。除了使用构造注入将变量赋值给static变量的方式外,还可以通过Aware接口进行getBean()的方式得到这些Bean.

    • SpringContextUtil

    使用的时候是不需要注入SpringContextUtil的,但是需要加上@Component让Spring感知到你的诉求.

    package com.xjm.bean.aware;
    
    import org.springframework.beans.BeansException;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.ApplicationContextAware;
    import org.springframework.stereotype.Component;
    
    /**
     * @author jaymin
     * 2021/1/10 16:22
     */
    @Component
    public class SpringContextUtil implements ApplicationContextAware {
    
        private static ApplicationContext applicationContext;
    
        @Override
        public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
            SpringContextUtil.applicationContext = applicationContext;
        }
    
        public static  <T> T getBean(String name, Class<T> requiredType) throws BeansException {
            return applicationContext.getBean(name, requiredType);
        }
    
    
    }
    
    • AwareDemo
    package com.xjm.bean.aware;
    
    import com.AnnotationContextDemo;
    import com.xjm.model.Person;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.annotation.AnnotationConfigApplicationContext;
    
    /**
     * @author jaymin
     * 2021/1/10 16:45
     */
    public class AwareDemo {
        public static void main(String[] args) {
            // 模拟容器启动,这里不直接使用该applicationContext,仅做组件扫描使用
            ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AnnotationContextDemo.class);
            Person person = SpringContextUtil.getBean("person", Person.class);
            System.out.println("通过Aware接口获取 person 对象:" + person.toString());
        }
    }
    
    • Result
    result

    我们通过实现ApplicationContextAware接口,访问到了整个容器上下文,并用简单的委派将getBean变成了静态方法调用。

    实现BeanNameAware访问BeanName

    • Person
    package com.xjm.model;
    
    import org.springframework.beans.factory.BeanNameAware;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Lazy;
    import org.springframework.stereotype.Component;
    import org.springframework.stereotype.Repository;
    
    /**
     * @author jaymin
     * 2020/11/28 0:02
     */
    @Repository
    public class Person implements BeanNameAware {
    
        private String name;
    
        private Integer age;
    
        public Person(String name) {
            this.name = name;
        }
    
        public Person() {
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    
        @Override
        public void setBeanName(String name) {
            System.out.println("Person Instance's Name is " + name);
        }
    }
    
    • Result
    result

    总结

    • Spring为了扩展性,不仅提供了容器刷新时会处理的后置处理器,而且提供了运行时感知的Aware来提供访问容器资源的接口。让开发者根据需求访问容器资源。
    • 每个单独的资源都对应一个Aware接口
    • 实现Aware接口的类也需要注册成Bean,Spring才会感知到其存在.

    相关文章

      网友评论

        本文标题:[Spring]Spring的Aware接口-装配

        本文链接:https://www.haomeiwen.com/subject/cmflaktx.html