spring-beans中Aware相关接口的源码解析说明

spring版本为5.0.11

Aware是个没有定义任何方法的接口,即标记超接口,拥有众多子接口,在spring源码中有多处都在使用这些子接口完成各种场景下的回调操作。

aware字面意思翻译过来是知道的,感知的,所以理解为感知所有aware前面的含义。

beanNameAware接口(不建议使用):如果某个bean需要访问配置文件中本身bean的id属性,这个Bean类通过实现该接口,在依赖关系确定之后,初始化方法之前,提供回调自身的能力,从而获得本身bean的id属性,该接口提供了void setBeanName(String name)方法实现,需要指出的是该方法的name参数就是该bean的id属性,加调该setBeanName方法可以让bean获取得自身的id属性,这个接口更多的使用在spring的框架代码中,实际开发环境应该不建议使用,因为spring认为bean的名字与bean的联系并不是很深。

BeanFactoryAware接口:实现了BeanFactoryAware接口的bean,可以直接通过beanfactory来访问spring的容器,当该bean被容器创建以后,会有一个相应的beanfactory的实例引用,该 接口有一个方法void setBeanFactory(BeanFactory beanFactory)方法通过这个方法的参数创建它的BeanFactory实例,实现了BeanFactoryAware接口,就可以让Bean拥有访问Spring容器的能力。缺点:导致代码与spring的api耦合在一起,这种方式不推荐。

ApplicationContextAware接口:在Bean类被初始化后,将会被注入applicationContext实例,该接口有一个方法,setApplicationContext(ApplicationContext context),使用其参数context用来创建它的applicationContext实例,缺点:导致代码与spring的api耦合在一起,这种方式不推荐。

MessageSourceAware接口:在Bean中可以得到消息源。

ApplicationEventPublisherAware接口:在bean中可以得到应用上下文的事件发布器,从而可以在Bean中发布应用上下文的事件。

ResourceLoaderAware接口:在Bean中可以得到ResourceLoader,从而在bean中使用ResourceLoader加载外部对应的Resource资源。

Aware接口的源码

/**
 * A marker superinterface indicating that a bean is eligible to be notified by the
 * Spring container of a particular framework object through a callback-style method.
 * The actual method signature is determined by individual subinterfaces but should
 * typically consist of just one void-returning method that accepts a single argument.
 *
 * <p>Note that merely implementing {@link Aware} provides no default functionality.
 * Rather, processing must be done explicitly, for example in a
 * {@link org.springframework.beans.factory.config.BeanPostProcessor}.
 * Refer to {@link org.springframework.context.support.ApplicationContextAwareProcessor}
 * for an example of processing specific {@code *Aware} interface callbacks.
 *
 * @author Chris Beams
 * @author Juergen Hoeller
 * @since 3.1
 */
public interface Aware {

}

从源码分析实现Aware接口被调起的原理:

从refresh上下文开始,prepareBeanFactory方法会添加ApplicationContextAwareProcessor后置处理器

触发getBean这个方法,在bean被初始化前,所有bean的后置处理器的postProcessBeforeInitialization方法都会被触发。

之前添加ApplicationContextAwareProcessor后置处理器的postProcessBeforeInitialization方法也会被触发

如果bean实现了某个接口,那么它的某个对应的方法就会被调用,然而没有BeanNameAware接口和BeanFactoryAware接口

AbstractAutowireCapableBeanFactory类的initializeBean方法会调用invokeAwareMethods(beanName, bean)方法

以BeanNameAware做个测试:

User1实现了BeanNameAware接口,User没有

public class User {
    private String id;
    private String name;
    private int age;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=‘" + id + ‘\‘‘ +
                ", name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}
public class User1 implements BeanNameAware {
    private String id;
    private String name;
    private int age;
    @Override
    public void setBeanName(String s) {
        id=s;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User1{" +
                "id=‘" + id + ‘\‘‘ +
                ", name=‘" + name + ‘\‘‘ +
                ", age=" + age +
                ‘}‘;
    }
}

注入

@Configuration
public class TestConfiguration {
    @Bean
    public User user(){
        User user = new User();
        user.setName("zhangsan");
        user.setAge(23);
        return user;
    }
    @Bean
    public User1 user1(){
        User1 user1=new User1();
        user1.setName("lisi");
        user1.setAge(24);
        return user1;
    }
}

测试:

    @Test
    public void test5(){
        AnnotationConfigApplicationContext applicationContext=new AnnotationConfigApplicationContext(TestConfiguration.class);
        User user = applicationContext.getBean(User.class);
        System.out.println(user);
        User1 user1 = applicationContext.getBean(User1.class);
        System.out.println(user1);
    }

得到打印结果:User没有获取到id属性

2020-01-22 15:21:36.079  INFO 9504 --- [           main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.spring[email protected]13dab28: startup date [Wed Jan 22 15:21:36 CST 2020]; root of context hierarchy
User{id=‘null‘, name=‘zhangsan‘, age=23}
User1{id=‘user1‘, name=‘lisi‘, age=24}
2020-01-22 15:21:36.107  INFO 9504 --- [       Thread-2] o.s.w.c.s.GenericWebApplicationContext   : Closing org.s[email protected]1485fda: startup date [Wed Jan 22 15:21:33 CST 2020]; root of context hierarchy

原文地址:https://www.cnblogs.com/mufeng07/p/12228687.html

时间: 2024-10-11 11:29:06

spring-beans中Aware相关接口的源码解析说明的相关文章

深入浅出 Spring Cache 使用与整合(附源码解析)

深入浅出 Spring Cache 使用与整合(附源码解析) 个人开发环境 java环境:Jdk1.8.0_60 编译器:IntelliJ IDEA 2019.1 springCache官方文档:https://docs.spring.io/spring/docs/5.1.9.RELEASE/spring-framework-reference/integration.html#cache 一.Spring缓存抽象 SpringCache产生的背景其实与Spring产生的背景有点类似.由于Jav

react 中间件相关的一些源码解析

零.随便说说中间件 在react的使用中,我们可以将数据放到redux,甚至将一些数据相关的业务逻辑放到redux,这样可以简化我们组件,也更方便组件抽离.封装.复用,只是redux不能很好的处理异步,当我们获取接口数据的时候,redux就满足不了我们的需要.然后,中间件就出来了,使用中间件可以满足我们异步获取数据,当然也可以干其他的事: 我们都知道一个数据更新,经过component >> action  >> dispatch >> reducers >>

安卓中的事件分发机制源码解析

安卓中的事件分发机制主要涉及到两类控件,一类是容器类控件ViewGroup,如常用的布局控件,另一类是显示类控件,即该控件中不能用来容纳其它控件,它只能用来显示一些资源内容,如Button,ImageView等控件.暂且称前一类控件为ViewGroup类控件(尽管ViewGroup本身也是一个View),后者为View类控件. 安卓中的事件分发机制主要涉及到dispatchTouchEvent(MotionEvent ev).onInterceptTouchEvent(MotionEvent e

Spring核心框架 - AOP的原理及源码解析

一.AOP的体系结构 如下图所示:(引自AOP联盟) 层次3语言和开发环境:基础是指待增加对象或者目标对象:切面通常包括对于基础的增加应用:配置是指AOP体系中提供的配置环境或者编织配置,通过该配置AOP将基础和切面结合起来,从而完成切面对目标对象的编织实现. 层次2面向方面系统:配置模型,逻辑配置和AOP模型是为上策的语言和开发环境提供支持的,主要功能是将需要增强的目标对象.切面和配置使用AOP的API转换.抽象.封装成面向方面中的逻辑模型. 层次1底层编织实现模块:主要是将面向方面系统抽象封

spring与ibatis集成之事务部分源码解析

ibatis是一个非常优秀的半自动ORM框架,相较于许多人认为编写sql和配置字段映射会降低开发效率,我认为在数据库最易成为系统瓶颈的情况下,开发人员必须通过手动编写sql来保证sql执行的高效,并在编写过程中思考表结构的设计是否合理.网上已有许多关于ibatis架构和映射实现原理解析的文章,本文主要讨论ibatis和spring集成后事务管理的实现.在spring和ibatis集成后,有两种方式执行sql:第一种是dao继承spring的SqlMapClientDaoSupport,具体的sq

高并发中使用到的RateLimiter源码解析

在开发高并发系统时有三把利器用来保护系统:缓存.降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高峰或者问题解决后再打开 限流 限流的目的是通过对并发访问/请求进行限速,或者对一个时间窗口内的请求进行限速来保护系统,一旦达到限制速率则可以拒绝服务.排队或等待.降级等处理 常用的限流算法有两种:漏桶算法和令牌桶算法 漏桶算法思路很简单,水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出,可以

IdentityServer4源码解析_4_令牌发放接口

目录 identityserver4源码解析_1_项目结构 identityserver4源码解析_2_元数据接口 identityserver4源码解析_3_认证接口 identityserver4源码解析_4_令牌发放接口 identityserver4源码解析_5_查询用户信息接口 identityserver4源码解析_6_结束会话接口 identityserver4源码解析_7_查询令牌信息接口 identityserver4源码解析_8_撤销令牌接口 协议 Token接口 oidc服

Spring源码解析-applicationContext

Demo uml类图 ApplicationContext ApplicationListener 源码解析 主流程 obtainFreshBeanFactory prepareBeanFactory invokeBeanFactoryPostProcessors registerBeanPostProcessors registerListeners finishRefresh 总结 在已经有BeanFactory可以完成Ioc功能情况下,spring又提供了ApplicationContex

spring源码解析前瞻

IOC.AOP是spring的2个核心特性.理解这2个特性,有助于更好的解析源码. IOC:控制反转.把创建对象的权利交给框架,这有利于解耦. public class PageController { public String showPage(){ PageService page = new PageService(); return ""; } } 原先PageController中使用PageService,需要自己new创建对象,使用spring后,由容器创建PageSe