Aware 容器感知技术
Spring的依赖注入的最大亮点:就是你所有的Bean对Spring容器的存在是没有意识的(我们的Bean并不需要实现它的任何接口)。即你可以将你的容器替换成别的容器,例如Goggle Guice,这时Bean之间的耦合度很低。
但是在实际的项目中,我们不可避免的要用到Spring容器本身的功能资源,这时候Bean必须要意识到Spring容器的存在,才能调用Spring所提供的资源,这就是所谓的Spring Aware。其实Spring Aware本来就是Spring设计用来框架内部使用的,若使用了Spring Aware,你的Bean将会和Spring框架耦合。
Spring提供Aware接口能让Bean感知Spring容器的存在,即让Bean可以使用Spring容器所提供的资源,下面是它提供给我们的感知器,我们一一简单介绍即可(因为使用起来太简单了):
- ApplicationContextAware:获取容器上下文
- BeanClassLoaderAware:获取加载当前Bean的类加载器
- BeanNameAware:获取当前Bean的名称
- LoadTimeWeaverAware:可以接收一个指向载入时(编译时)时织入实例的引用,实现编译时代理,属于比较高端的。可参见AspectJWeavingEnabler
- BootstrapContextAware:拿到资源适配器BootstrapContext上下文,如JCA,CCI
- ServletConfigAware:获取到ServletConfig
- ImportAware:获取到AnnotationMetadata等信息。这个挺重要的,比如AbstractCachingConfiguration、AbstractTransactionManagementConfiguration都通过实现这个接口来获取到了注解的属性们。比如@EnableAsync、EnableCaching等注解上的属性值 参考:Spring的@Import注解与ImportAware接口
- EmbeddedValueResolverAware:能让我们拿到StringValueResolver这个处理器,这样我们就可以很好的处理配置文件的值了。我们可以做个性化处理(比如我们自己要书写一个属性获取的工具类之类的。。。)
- EnvironmentAware:拿到环境Environment
- BeanFactoryAware:获取Bean Factory
- NotificationPublisherAware:和JMX有关
- ResourceLoaderAware:获取资源加载器ResourceLoader可以获得外部资源文件 比如它的:ResourceLoader#getResource方法
- MessageSourceAware:获取国际化文本信息
- ServletContextAware:获取ServletContext
- ApplicationEventPublisher:拿到事件发布器
备注:在高版本的Spring容器中,这些基础组件基本上(大多数)都能直接Autowired了,比如ApplicationContext、BeanFactory等等,有时候使用起来更加的方便
ResolvableType:可解决的数据类型(更好的处理泛型)
之前有有讲过JDK对泛型抽象的文章:【小家Java】你真的了解Java泛型参数吗?细说java.lang.reflect.Type(ParameterizedType、TypeVariable、WildcardType…)
今儿说说Spring为我们提供的ResolvableType:它为java语言中的所有类型提供了相同的数据结构,其内部封装了一个java.lang.reflect.Type类型的对象
ResolvableType为所有的java类型提供了统一的数据结构以及API ,换句话说,一个ResolvableType对象就对应着一种java类型。 下面我们看看具体的使用
获取对象
ResolvableType所有构造函数都是私有的。我们不能直接new,只能使用其提供的静态方法进行类型获取
public static ResolvableType forClass(@Nullable Class<?> clazz); public static ResolvableType forRawClass(@Nullable Class<?> clazz); public static ResolvableType forClass(Class<?> baseType, Class<?> implementationClass); public static ResolvableType forMethodReturnType(Method method); //获取指定方法的返回值的类型 ...见下面截图,非常非常多
提供的方法举例:
- getSuperType():获取直接父类型
- getInterfaces():获取接口类型们
- getGenerics():获取类型携带的泛型类型
- resolve():Type对象到Class对象的转换(使用得非常多)
- isInstance、isAssignableFrom。。。
- .ResolvableType.forInstance 获取指定的实例的泛型信息
提供一个案例参考:
public static void main(String[] args) { ResolvableType type = ResolvableType.forClass(ArrayList.class); System.out.println(type); //java.util.ArrayList<?> System.out.println(type.getType()); //class java.util.ArrayList System.out.println(type.getComponentType()); //? System.out.println(type.getInterfaces()); //[Lorg.springframework.core.ResolvableType;@4b4523f8 System.out.println(type.getSuperType()); //java.util.AbstractList<?> System.out.println(type.getRawClass()); //class java.util.ArrayList System.out.println(type.getSource()); //class java.util.ArrayList System.out.println(type.getGenerics()); //[Lorg.springframework.core.ResolvableType;@1f28c152 System.out.println(type.resolve()); //class java.util.ArrayList }
Spring还提供了一个专门处理泛型的工具类:GenericTypeResolver,非常的强大。比如常用使用场景:
this.genericType = (Class<T>) GenericTypeResolver.resolveTypeArgument(getClass(), GenericDaoSupport.class);
还有:GenericTypeResolver.resolveParameterType…方法
总结
这篇博文主要是单独摘出来讲解Spring在处理过程中,用到一些内部工具性质的处理组件进行讲解~
Spring是面向对象编程的典范工程,对封装、适配、抽象做得非常到位,希望这些东西我们也能学以致用~