你好呀,我是沉默王二,一个和黄家驹一样身高,刘德华一样颜值的程序员(不信围观朋友圈呗)。从 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 类,内容如下:
@Configurationpublic 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如果把 @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 是否为一个单例。