趣学Spring:一文搞懂Aware、异步编程、计划任务(1)

简介: 趣学Spring:一文搞懂Aware、异步编程、计划任务

你好呀,我是沉默王二,一个和黄家驹一样身高,刘德华一样颜值的程序员(不信围观朋友圈呗)。从 2 位偶像的年纪上,你就可以断定我的码龄至少在 10 年以上,但实话实说,我一直坚信自己只有 18 岁,因为好学使我年轻。本篇文章就打算通过我和三妹对话的形式来聊一聊“Spring 的 Aware、异步编程、计划任务”。


教妹学 Spring,没见过这么放肆的标题吧?“语不惊人死不休”,没错,本篇文章的标题就是这么酷炫,不然你怎么会点进来?




我有一个漂亮如花的妹妹(见上图,怎么又变了?还不能一天做个梦),她叫什么呢?我想聪明的读者能猜得出:沉默王三,没错,年方三六。父母正考虑让她向我学习,做一名正儿八经的 Java 程序员。我一开始是反对的,因为程序员这行业容易掉头发,女生可不适合掉头发。但家命难为啊,与其反对,不如做点更积极的事情,比如说写点有趣的文章教教她。




“二哥,听说今天要学习 Spring 的 Aware、异步编程、计划任务,真的是翘首以盼啊。”


“哎呀,三妹,瞧你那迫不及待的大眼神,就好像昨晚上月亮一样圆,一样大。”


01、Spring Aware


“二哥,据说 Aware 的目的是让 Bean 获取 Spring 容器的服务,你能给我具体说说吗?”


“没问题啊。”


Bean 一般不需要了解容器的状态和直接使用容器,但是在某些情况下,需要在 Bean 中直接对容器进行操作,这时候,就可以通过特定的 Aware 接口来完成。常见的 Spring Aware 接口有下面这些:


Aware 子接口 描述

BeanNameAware 获取容器中 Bean 的名称

BeanFactoryAware Bean 被容器创建以后,会有一个相应的 BeanFactory,可以直接通过它来访问容器

ApplicationContextAware Bean 被初始化后,会被注入到 ApplicationContext,可以直接通过它来访问容器

MessageSourceAware 获取 Message Source 的相关文本信息

ResourceLoaderAware 获取资源加载器,以获取外部资源文件

1)BeanNameAware


新建一个 MyBeanName 类,内容如下:


public class MyBeanName implements BeanNameAware {
    @Override
    public void setBeanName(String beanName) {
        System.out.println(beanName);
    }
}


MyBeanName 实现了 BeanNameAware 接口,并重写了 setBeanName() 方法。beanName 参数表示 Bean 在 Spring 容器中注册的 name。


新建一个 Config 类,内容如下:


@Configuration
public class Config {
    @Bean(name = "myCustomBeanName")
    public MyBeanName getMyBeanName() {
        return new MyBeanName();
    }
}



@Bean 注解用在 getMyBeanName() 方法上,表明当前方法返回一个 Bean 对象(MyBeanName),并通过 name 属性指定 Bean 的名字为“myCustomBeanName”。


新建 BeanNameMain 类,代码如下:


public class BeanNameMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(BeanNameConfig.class);
        MyBeanName myBeanName = context.getBean(MyBeanName.class);
        context.close();
    }
}


程序输出的结果如下所示:


myCustomBeanName

1

如果把 @Bean() 注解中的 (name = "myCustomBeanName)" 去掉的话,程序输出的内容将会是 BeanNameConfig 类的 getMyBeanName() 的方法名“getMyBeanName”。


2)BeanFactoryAware


新建一个 MyBeanFactory 类,内容如下:


public class MyBeanFactory implements BeanFactoryAware {
    private BeanFactory beanFactory;
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
    public void getMyBeanName() {
        MyBeanName myBeanName = beanFactory.getBean(MyBeanName.class);
        System.out.println(beanFactory.isSingleton("myCustomBeanName"));
        System.out.println(beanFactory.isSingleton("getMyBeanFactory"));
    }
}



借助 setBeanFactory() 方法,可以将容器中的 BeanFactory 赋值给 MyBeanFactory 类的成员变量 beanFactory,这样就可以在 getMyBeanName() 方法中使用 BeanFactory 了。


通过 getBean() 方法可以获取 Bean 的实例;通过 isSingleton() 方法判断 Bean 是否为一个单例。


在 Config 类中追加 MyBeanFactory 的 Bean:


@Configuration
public class Config {
    @Bean(name = "myCustomBeanName")
    public MyBeanName getMyBeanName() {
        return new MyBeanName();
    }
    @Bean
    public MyBeanFactory getMyBeanFactory() {
        return new MyBeanFactory();
    }
}



新建 BeanFactoryMain 类,代码如下:


public class BeanFactoryMain {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class);
        MyBeanFactory myBeanFactory = context.getBean(MyBeanFactory.class);
        myBeanFactory.getMyBeanName();
        context.close();
    }
}



初始化 MyBeanFactory 后就可以调用 getMyBeanName() 方法了,程序输出的结果如下所示:


myCustomBeanName

true

true


结果符合我们的预期:MyBeanName 的名字为“myCustomBeanName”,MyBeanName 和 MyBeanFactory 的 scope 都是 singleton。


3)其他几个 Aware 接口就不再举例说明了。通常情况下,不要实现 Aware 接口,因为它会使 Bean 和 Spring 框架耦合。


相关文章
|
2月前
|
传感器 Java API
Spring揭秘:Aware接口应用场景及实现原理!
Aware接口赋予了Bean更多自感知的能力,通过实现不同的Aware接口,Bean可以轻松地获取到Spring容器中的其他资源引用,像ApplicationContext、BeanFactory等。 这样不仅增强了Bean的功能,还提高了代码的可维护性和扩展性,从而让Spring的IoC容器变得更加强大和灵活。
132 0
Spring揭秘:Aware接口应用场景及实现原理!
|
4月前
|
Java Spring 容器
深入Spring原理-4.Aware接口、初始化和销毁执行顺序、Scope域
深入Spring原理-4.Aware接口、初始化和销毁执行顺序、Scope域
75 0
|
11月前
|
Java Spring 容器
深入理解Spring IOC之扩展篇(四)、Aware接口
深入理解Spring IOC之扩展篇(四)、Aware接口
109 0
|
设计模式 Java Spring
Spring Aware接口详解
若 Spring 检测到 bean 实现了 Aware 接口,则会为其注入相应的依赖。所以通过让bean 实现 Aware 接口,则能在 bean 中获得相应的 Spring 容器资源。
153 0
|
Java 程序员 网络安全
spring4.1.8扩展实战之二:Aware接口揭秘
Aware.java是个没有定义任何方法的接口,拥有众多子接口,在spring源码中有多处都在使用这些子接口完成各种场景下的回调操作,当业务有需要时,我们只需创建类来实现相关接口,再声明为bean,就可以被spring容器主动回调
235 0
spring4.1.8扩展实战之二:Aware接口揭秘
|
缓存 Java Spring
Spring Aware 介绍
读完这篇文章你将会收获到 • Aware 的使用和介绍 • BeanFactoryAware 的触发时机 • ApplicationContextAware 的触发时机以及它通过扩展 BeanPostProcessor 来实现
191 0
|
安全 Java Spring
Spring Aware 到底是什么?
Spring Aware 到底是什么?
Spring Aware 到底是什么?
|
Java Maven Spring
【Spring】Spring高级话题-Spring Aware
【Spring】Spring高级话题-Spring Aware
177 0
【Spring】Spring高级话题-Spring Aware
|
设计模式 XML Java
《Spring 手撸专栏》第 9 章:虎行有雨,定义标记类型Aware接口,实现感知容器对象
实现 1. 工程结构 2. 定义标记接口 3. 容器感知类 4. 包装处理器(ApplicationContextAwareProcessor) 5. 注册 BeanPostProcessor 6. 感知调用操作 测试 1. 事先准备 2. 配置文件 3. 单元测试
159 0
《Spring 手撸专栏》第 9 章:虎行有雨,定义标记类型Aware接口,实现感知容器对象
|
Java Spring 容器
SPRING07_源码之核心组件接口Aware
写在最前面 由于这部分内容涉及到了后面的处理器,这里只简单介绍
SPRING07_源码之核心组件接口Aware