上篇:【springboot高级】(五:九大常用Aware实现、作用以及自定义实现类使用,例子:ApplicationContextAware (使用篇))
注意:如果只是想直接使用,不看原理的,请移步至【spring方法最全面,注释最全面的上下文工具类,拿走不谢,不来复制去使用太可惜了】SpringContextUtils
我们将到了Aware的作用以及基本使用,并且例举了最常用的九大Aware实现,以表格的形式展示了其作用。
那么这节我们将详细讲解ApplicationContextAware,他传递给我们的参数:上下文对象ApplicationContext我们应该如何使用,它给我提供了哪些api,那些api我们工作中比较常用。
使用如下:
package com.osy.aware;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.util.Optional;
@Component
public class MyApplicationContextAware implements ApplicationContextAware {
private ApplicationContext applicationContext;
/**
* springboot会回调这个函数,
* 他回调的时候,会将ApplicationContext对象传递给我们,那么我们就获取获取到他,并且做一些事情。
* @param applicationContext
* @throws BeansException
*/
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
Optional.ofNullable(this.applicationContext).orElse(this.applicationContext = applicationContext);
}
}
首先,ApplicationContext 是一个接口,他么springboot传递给我们的应该会是一个具体的类,但是这个接口下面有很多的实现类,这个我们我们就打一个断点看一下他传递过来的具体是哪个类。
从这里我们可以看出是:AnnotationConfigServletWebServerApplicationContext
因为们这个项目是web项目,所以返回的应该就是关于web方面的具体实现类了。
看这个名字就是注解配置的提供web服务的应用上下文。从这里可以猜测出不同的环境,它传递过来的子类是不一样的。
让我们我继续看ApplicationContext这个接口。
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
// 获取此上下文的唯一id,可以为空
@Nullable
String getId();
// 返回此上下文所属的应用程序的名称。
String getApplicationName();
// 返回此上下文的友好名称:返回通俗易懂的应用名称
String getDisplayName();
// 返回首次加载此上下文时的时间戳。
long getStartupDate();
// 返回父上下文,如果没有父上下文则返回Null
@Nullable
ApplicationContext getParent();
// 这个翻译出来比较长,反正看到一句:这通常不被应用程序代码使用,还是算了吧。抓重点
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
}
看这个接口的方法,对于实际开发,实质性的东西并不多。
那么我们继续来看他所继承的几大接口:
1、EnvironmentCapable:方法只有一个,当前的环境:
public interface EnvironmentCapable {
Environment getEnvironment();
}
这个环境还是有一点用的:
提供了一很多方法可以给我们使用。可以获取系统的配置,也可以获取我们自己在配置文件中的配置。这个对象和我们实现EnvironmentAware 获取到的对象应该是一致的。
2、ListableBeanFactory:这个接口的方法有很多,都是一些关于bean各种操作的方法。对于我们的应用很是实用。
public interface ListableBeanFactory extends BeanFactory {
// 检查这个bean工厂是否包含具有给定名称的bean定义。
boolean containsBeanDefinition(String beanName);
// 返回工厂中定义的bean数。
int getBeanDefinitionCount();
// 返回此工厂中定义的所有bean的名称。
String[] getBeanDefinitionNames();
// 返回给定类型(包括子类)的bean的名称
String[] getBeanNamesForType(@Nullable Class<?> type);
// 返回与给定对象类型匹配的bean实例,通过map返回(key:bean的名字,value:bean的实例)
<T> Map<String, T> getBeansOfType(@Nullable Class<T> type) throws BeansException;
// 查找指定注解的所有bean的名称
String[] getBeanNamesForAnnotation(Class<? extends Annotation> annotationType);
// 用于查找bean类上面是否有我们指定的注解。看到这里我倒是突发奇想:
// 我们是不是可以对其进行开发的约束,比如对所有contronller里面的,都必须打上controller注解。
// 当然这只是一个个人想法。不喜勿喷
@Nullable
<A extends Annotation> A findAnnotationOnBean(String beanName, Class<A> annotationType)
throws NoSuchBeanDefinitionException;
}
3、HierarchicalBeanFactory:就两个方法
public interface HierarchicalBeanFactory extends BeanFactory {
// 返回父bean工厂,如果没有父bean工厂,则返回{@code null}。
@Nullable
BeanFactory getParentBeanFactory();
// 返回本地bean工厂是否包含给定名称的bean,忽略祖先上下文中定义的bean
boolean containsLocalBean(String name);
}
4、MessageSource:消息解析
public interface MessageSource {
// 尝试解析消息。如果没有找到消息,则返回默认消息。
// locale,我们就传入Locale.TRADITIONAL_CHINESE即可,因为这个代表中文
@Nullable
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
// 尝试解析消息。如果找不到消息,则视为错误,程序报错
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
}
5、ApplicationEventPublisher:事件发布
@FunctionalInterface
public interface ApplicationEventPublisher {
// 通知所有与此注册的事件匹配的侦听器,应用程序事件的应用程序。建议事件处理使用异步,一提高系统启动效率
// 这是它的默认方法。我们尽量不要去使用它。
default void publishEvent(ApplicationEvent event) {
publishEvent((Object) event);
}
// 如果我们要使用,那么就覆盖此方法,去通知我们自己定义的事件
void publishEvent(Object event);
}
6、ResourcePatternResolver:资源解析器
public interface ResourcePatternResolver extends ResourceLoader {
String CLASSPATH_ALL_URL_PREFIX = "classpath*:";
// 将给定的位置模式解析为资源对象。
Resource[] getResources(String locationPattern) throws IOException;
}