外链网站大全,企业内部网站建设方案,行业网站维护,做网站代码用什么软件#x1f3ac;作者简介#xff1a;大家好#xff0c;我是小徐#x1f947;☁️博客首页#xff1a;CSDN主页小徐的博客#x1f304;每日一句#xff1a;好学而不勤非真好学者 #x1f4dc; 欢迎大家关注#xff01; ❤️ #xfeff;AbstractAutowireCapableBeanFacto… 作者简介大家好我是小徐☁️博客首页CSDN主页小徐的博客每日一句好学而不勤非真好学者 欢迎大家关注 ❤️ AbstractAutowireCapableBeanFactory 的 #doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 方法主要干三件事情
实例化 bean 对象#createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) 方法。属性注入#populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) 方法。初始化 bean 对象#initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) 方法。
而初始化 bean 对象时也是干了三件事情
激活 Aware 方法后置处理器的应用激活自定义的 init 方法
这篇主要分析 Aware 接口。
1. Aware 接口
org.springframework.beans.factory.Aware 接口定义如下
/*** 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. Actual method signature is* determined by individual subinterfaces, but should typically* consist of just one void-returning method that accepts a single* argument.** pNote 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 BeanPostProcessor}.* Refer to {link org.springframework.context.support.ApplicationContextAwareProcessor}* and {link org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory}* for examples of processing {code *Aware} interface callbacks.** author Chris Beams* since 3.1*/
public interface Aware {}
Aware 接口为 Spring 容器的核心接口是一个具有标识作用的超级接口实现了该接口的 bean 是具有被 Spring 容器通知的能力通知的方式是采用回调的方式。
Aware 接口是一个空接口实际的方法签名由各个子接口来确定且该接口通常只会有一个接收单参数的 set 方法该 set 方法的命名方式为 set 去掉接口名中的 Aware 后缀即 XxxAware 接口则方法定义为 setXxx()例如 BeanNameAwaresetBeanNameApplicationContextAwaresetApplicationContext。
Aware 的子接口需要提供一个 setXxx 方法我们知道 set 是设置属性值的方法即 Aware 类接口的 setXxx 方法其实就是设置 xxx 属性值的。 Aware 的含义是感知的、感应的那么在 Spring 容器中是如何实现感知并设置属性值得呢我们可以从初始化 bean 中的激活 Aware 的方法 #invokeAwareMethods(final String beanName, final Object bean) 中看到一点点代码如下
// AbstractAutowireCapableBeanFactory.javaprivate void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {// BeanNameAwareif (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}// BeanClassLoaderAwareif (bean instanceof BeanClassLoaderAware) {ClassLoader bcl getBeanClassLoader();if (bcl ! null) {((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);}}// BeanFactoryAwareif (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}
}
首先判断 bean 实例是否属于 Aware 接口的范畴如果是的话则调用实例的 setXxx() 方法给实例设置 xxx 属性值在 #invokeAwareMethods(...) 方法主要是设置 beanNamebeanClassLoader、BeanFactory 中三个属性值。
2. Aware 子类
Spring 提供了一系列的 Aware 接口如下图部分上面只是一部分子类从这里我们可以看到 Spring 提供的 Aware 接口是是何其多。同时从上图我们也看到了几个比较熟悉的接口如 BeanClassLoaderAware、BeanFactoryAware、BeanNameAware下面就这三个接口来做一个简单的演示先看各自的定义
public interface BeanClassLoaderAware extends Aware {/*** 将 BeanClassLoader 提供给 bean 实例回调* 在 bean 属性填充之后、初始化回调之前回调* 例如InitializingBean的InitializingBean.afterPropertiesSet方法或自定义init方法*/void setBeanClassLoader(ClassLoader classLoader);}public interface BeanFactoryAware extends Aware {/*** 将 BeanFactory 提供给 bean 实例回调* 调用时机和 setBeanClassLoader 一样*/void setBeanFactory(BeanFactory beanFactory) throws BeansException;}public interface BeanNameAware extends Aware {/*** 在创建此 bean 的 bean工厂中设置 beanName*/void setBeanName(String name);}public interface ApplicationContextAware extends Aware {/*** 设置此 bean 对象的 ApplicationContext通常该方法用于初始化对象*/void setApplicationContext(ApplicationContext applicationContext)throws BeansException;}
2.1 示例
下面简单演示下上面四个接口的使用方法
public class MyApplicationAware implements BeanNameAware,BeanFactoryAware,BeanClassLoaderAware,ApplicationContextAware{private String beanName;private BeanFactory beanFactory;private ClassLoader classLoader;private ApplicationContext applicationContext;Overridepublic void setBeanClassLoader(ClassLoader classLoader) {System.out.println(调用了 BeanClassLoaderAware 的 setBeanClassLoader 方法);this.classLoader classLoader;}Overridepublic void setBeanFactory(BeanFactory beanFactory) throws BeansException {System.out.println(调用了 BeanFactoryAware 的 setBeanFactory 方法);this.beanFactory beanFactory;}Overridepublic void setBeanName(String name) {System.out.println(调用了 BeanNameAware 的 setBeanName 方法);this.beanName name;}Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {System.out.println(调用了 ApplicationContextAware 的 setApplicationContext 方法);this.applicationContext applicationContext;}public void display(){System.out.println(beanName: beanName);System.out.println(是否为单例 beanFactory.isSingleton(beanName));System.out.println(系统环境为 applicationContext.getEnvironment());}
}
测试方法如下:
public static void main(String[] args) {ClassPathResource resource new ClassPathResource(spring.xml);DefaultListableBeanFactory factory new DefaultListableBeanFactory();XmlBeanDefinitionReader reader new XmlBeanDefinitionReader(factory);reader.loadBeanDefinitions(resource);MyApplicationAware applicationAware (MyApplicationAware) factory.getBean(myApplicationAware);applicationAware.display();
}
运行结果从该运行结果可以看出这里只执行了三个 Aware 接口的 set 方法原因就是通过 #getBean(...) 方法调用时在激活 Aware 接口时只检测了 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware 三个 Aware 接口。如果将测试方法调整为下面
public static void main(String[] args) {ApplicationContext applicationContext new ClassPathXmlApplicationContext(spring.xml);MyApplicationAware applicationAware (MyApplicationAware) applicationContext.getBean(myApplicationAware);applicationAware.display();
}
则运行结果如下
3. 总结
从本文我们基本上就可以 Aware 真正的含义是什么了感知其实是 Spring 容器在初始化主动检测当前 bean 是否实现了 Aware 接口如果实现了则回调其 set 方法将相应的参数设置给该 bean 这个时候该 bean 就从 Spring 容器中取得相应的资源。
最后文章末尾列出部分常用的 Aware 子接口便于日后查询
LoadTimeWeaverAware加载Spring Bean时织入第三方模块如AspectJBeanClassLoaderAware加载Spring Bean的类加载器BootstrapContextAware资源适配器BootstrapContext如JCA,CCIResourceLoaderAware底层访问资源的加载器BeanFactoryAware声明BeanFactoryPortletConfigAwarePortletConfigPortletContextAwarePortletContextServletConfigAwareServletConfigServletContextAwareServletContextMessageSourceAware国际化ApplicationEventPublisherAware应用事件NotificationPublisherAwareJMX通知BeanNameAware声明Spring Bean的名字