为何重拾
使用了 Spring 多年, 但是对其底层的一些实现还是一知半解, 一些概念比较模糊; 故决定重新拾起, 加深对 Spring 的认识.
重拾计划
spring 版本说明
Spring 在经过多年的演进过程中, 其功能越来越丰富, 组件越来越多; 为了避免在阅读源码的过程中深陷泥潭中, 决定采用最原始的版本 1.0; 但又不局限于 1.0 版本.
- spring IoC
- spring aop
spring 事务管理
spring ORM 集成
实现分析
Spring 容器启动
在本文中, 通过常用的构造 ClassPathXmlApplicationContext 实例来作为对 Spring 实现分析的入口
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
通过调用链追踪, Spring 容器启动核心操作由 AbstractApplicationContext 类中 refresh 方法实现
- public void refresh() throws BeansException {
- this.startupTime = System.currentTimeMillis();
- // tell subclass to refresh the internal bean factory
- // 完成 xml 配置文件的解析, 解析 bean 标签生成 BeanDefinition 对象, 并注册到 BeanFactory
- refreshBeanFactory();
- ConfigurableListableBeanFactory beanFactory = getBeanFactory();
- // configure the bean factory with context semantics
- beanFactory.registerCustomEditor(Resource.class, new ContextResourceEditor(this));
- beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
- beanFactory.ignoreDependencyType(ResourceLoader.class);
- beanFactory.ignoreDependencyType(ApplicationContext.class);
- postProcessBeanFactory(beanFactory);
- // invoke factory processors registered with the context instance
- // 获取内置 BeanFactoryPostProcessor 实例, 并遍历调用 postProcessBeanFactory 方法
- // 对 BeanFactory 进行后置处理
- for (Iterator it = getBeanFactoryPostProcessors().iterator(); it.hasNext();) {
- BeanFactoryPostProcessor factoryProcessor = (BeanFactoryPostProcessor) it.next();
- factoryProcessor.postProcessBeanFactory(beanFactory);
- }
- if (getBeanDefinitionCount() == 0) {
- logger.warn("No beans defined in ApplicationContext [" + getDisplayName() + "]");
- }
- else {
- logger.info(getBeanDefinitionCount() + "beans defined in ApplicationContext [" + getDisplayName() + "]");
- }
- // invoke factory processors registered as beans in the context
- // 从 Bean Definition 集合中查找 BeanFactoryPostProcessor 定义并实例化
- // 获取 BeanFactoryPostProcessor 实例, 并遍历调用 postProcessBeanFactory 方法
- // 对 BeanFactory 进行后置处理
- invokeBeanFactoryPostProcessors();
- // register bean processor that intercept bean creation
- // 从 Bean Definition 集合中查找 BeanPostProcessor 类定义实例化并注册到 BeanFactory 中
- registerBeanPostProcessors();
- // initialize message source for this context
- initMessageSource();
- // initialize other special beans in specific context subclasses
- onRefresh();
- // check for listener beans and register them
- refreshListeners();
- // instantiate singletons this late to allow them to access the message source
- // 对 Bean Definition 中单例且非延迟加载的类型进行实例化
- /**
- * bean 初始化过程如下:
- * 1 : bean 构造初始化
- * 2 : bean 属性注入 (通过 bean definition 中的 property , autowire(byType, byName) 实现)
- * 3 : bean 若实现 BeanNameAware 接口, 调用 setBeanName() 方法
- * 4 : bean 若实现 BeanFactoryAware 接口, 调用 setBeanFactory() 方法
- * 5 : 遍历调用 BeanFactory 中注册的 BeanPostProcessor 实例的 postProcessorBeforeInitialization() 方法
- * 6 : bean 若实现了 InitializingBean 接口, 调用 afterPropertiesSet() 方法
- * 7 : bean 实例对应的 bean definition 中若定义了 init-method 属性则调用对应的 init 方法
- * 8 : 遍历调用 BeanFactory 中注册的 BeanPostProcessor 实例的 postProcessorAfterInitialization() 方法
- */
- beanFactory.preInstantiateSingletons();
- // last step: publish respective event
- publishEvent(new ContextRefreshedEvent(this));
- }
从源码中可知, Spring 容器在启动过程中, 主要完成以下流程 :
通过加载指定的配置文件, 完成 Bean Definition 解析并注册到 BeanFactory 实例中
通过内置及应用自定义的 BeanFactoryPostProcessor 对 BeanFactory 实例进行后置处理
实例化应用自定义的 BeanPostProcessor 并注册到 BeanFactory 实例中
实例化 Spring 容器中的 Bean
Spring 容器关闭
- public void close() {
- logger.info("Closing application context [" + getDisplayName() + "]");
- // destroy all cached singletons in this context,
- // invoking DisposableBean.destroy and/or "destroy-method"
- // 销毁容器中缓存的单例对象实例
- // 执行容器中 DisposableBean 的 destroy 方法
- getBeanFactory().destroySingletons();
- // publish respective event
- // 发送 spring 上下文关闭事件
- publishEvent(new ContextClosedEvent(this));
- }
通过调用链追踪, Spring 会遍历容器中缓存的 bean 实例调用 destroyBean 方法.
- protected void destroyBean(String beanName, Object bean) {
- logger.debug("Retrieving depending beans for bean'" + beanName + "'");
- // 先销毁所有依赖当前 bean 的实例
- String[] dependingBeans = getDependingBeanNames(beanName);
- if (dependingBeans != null) {
- for (int i = 0; i <dependingBeans.length; i++) {
- destroySingleton(dependingBeans[i]);
- }
- }
- if (bean instanceof DisposableBean) {
- // 如果 bean 实现了 DisposableBean 接口, 将会执行 destroy 方法
- logger.debug("Calling destroy() on bean with name'" + beanName + "'");
- try {
- ((DisposableBean) bean).destroy();
- }
- catch (Exception ex) {
- logger.error("destroy() on bean with name'" + beanName + "'threw an exception", ex);
- }
- }
- try {
- RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
- if (bd.getDestroyMethodName() != null) {
- // 如果 bean 定义了 destroy-method 属性, 将会调用自定义的销毁方法
- logger.debug("Calling custom destroy method'" + bd.getDestroyMethodName() +
- "'on bean with name'" + beanName + "'");
- invokeCustomDestroyMethod(beanName, bean, bd.getDestroyMethodName());
- }
- }
- catch (NoSuchBeanDefinitionException ex) {
- // ignore, from manually registered singleton
- }
- }
下面将针对 Spring Bean 在容器启动过程中的各个环节的实现进行详细说明
Spring Bean 定义解析
通过对 refreshBeanFactory 方法的调用链追踪, 可以看到在 DefaultXmlBeanDefinitonParser 类的 registerBeanDefinitions 方法中实现对 Spring Bean 定义的解析及注册.
- public void registerBeanDefinitions(BeanDefinitionRegistry beanFactory, ClassLoader beanClassLoader,
- Document doc, Resource resource) {
- this.beanFactory = beanFactory;
- this.beanClassLoader = beanClassLoader;
- this.resource = resource;
- logger.debug("Loading bean definitions");
- Element root = doc.getDocumentElement();
- this.defaultLazyInit = root.getAttribute(DEFAULT_LAZY_INIT_ATTRIBUTE);
- logger.debug("Default lazy init'" + this.defaultLazyInit + "'");
- this.defaultDependencyCheck = root.getAttribute(DEFAULT_DEPENDENCY_CHECK_ATTRIBUTE);
- logger.debug("Default dependency check'" + this.defaultDependencyCheck + "'");
- this.defaultAutowire = root.getAttribute(DEFAULT_AUTOWIRE_ATTRIBUTE);
- logger.debug("Default autowire'" + this.defaultAutowire + "'");
- NodeList nl = root.getChildNodes();
- int beanDefinitionCounter = 0;
- for (int i = 0; i < nl.getLength(); i++) {
- Node node = nl.item(i);
- if (node instanceof Element && BEAN_ELEMENT.equals(node.getNodeName())) {
- beanDefinitionCounter++;
- loadBeanDefinition((Element) node);
- }
- }
- logger.debug("Found" + beanDefinitionCounter + "<" + BEAN_ELEMENT + "> elements defining beans");
- }
- protected void loadBeanDefinition(Element ele) {
- // 获取 bean 的 id, name 属性
- String id = ele.getAttribute(ID_ATTRIBUTE);
- String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
- List aliases = new ArrayList();
- if (nameAttr != null && !"".equals(nameAttr)) {
- String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, BEAN_NAME_DELIMITERS, true, true);
- aliases.addAll(Arrays.asList(nameArr));
- }
- if (id == null || "".equals(id) && !aliases.isEmpty()) {
- id = (String) aliases.remove(0);
- logger.debug("No XML'id'specified - using'" + id + "'as ID and" + aliases + "as aliases");
- }
- // 解析 bean 标签, 获取 bean 配置的属性, 构造, 是否懒加载 作用域
- AbstractBeanDefinition beanDefinition = parseBeanDefinition(ele, id);
- if (id == null || "".equals(id)) {
- if (beanDefinition instanceof RootBeanDefinition) {
- id = ((RootBeanDefinition) beanDefinition).getBeanClassName();
- logger.debug("Neither XML'id'nor'name'specified - using bean class name [" + id + "] as ID");
- }
- else {
- throw new BeanDefinitionStoreException(this.resource, "","Child bean definition has neither 'id' nor 'name'");
- }
- }
- logger.debug("Registering bean definition with id'" + id + "'");
- // 将 bean definiton 注册到 beanFactory
- this.beanFactory.registerBeanDefinition(id, beanDefinition);
- for (Iterator it = aliases.iterator(); it.hasNext();) {
- this.beanFactory.registerAlias(id, (String) it.next());
- }
- }
- protected AbstractBeanDefinition parseBeanDefinition(Element ele, String beanName) {
- String className = null;
- try {
- // 获取 class 属性
- if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
- className = ele.getAttribute(CLASS_ATTRIBUTE);
- }
- String parent = null;
- if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
- parent = ele.getAttribute(PARENT_ATTRIBUTE);
- }
- if (className == null && parent == null) {
- throw new BeanDefinitionStoreException(this.resource, beanName, "Either'class'or'parent'is required");
- }
- AbstractBeanDefinition bd = null;
- // 获取属性
- MutablePropertyValues pvs = getPropertyValueSubElements(beanName, ele);
- if (className != null) {
- // 获取构造
- ConstructorArgumentValues cargs = getConstructorArgSubElements(beanName, ele);
- RootBeanDefinition rbd = null;
- if (this.beanClassLoader != null) {
- Class clazz = Class.forName(className, true, this.beanClassLoader);
- rbd = new RootBeanDefinition(clazz, cargs, pvs);
- }
- else {
- rbd = new RootBeanDefinition(className, cargs, pvs);
- }
- // 设置 bean dependOn
- if (ele.hasAttribute(DEPENDS_ON_ATTRIBUTE)) {
- String dependsOn = ele.getAttribute(DEPENDS_ON_ATTRIBUTE);
- rbd.setDependsOn(StringUtils.tokenizeToStringArray(dependsOn, BEAN_NAME_DELIMITERS, true, true));
- }
- String dependencyCheck = ele.getAttribute(DEPENDENCY_CHECK_ATTRIBUTE);
- if (DEFAULT_VALUE.equals(dependencyCheck)) {
- dependencyCheck = this.defaultDependencyCheck;
- }
- rbd.setDependencyCheck(getDependencyCheck(dependencyCheck));
- // 设置 bean 自动注册的方式 byType, byName or none
- String autowire = ele.getAttribute(AUTOWIRE_ATTRIBUTE);
- if (DEFAULT_VALUE.equals(autowire)) {
- autowire = this.defaultAutowire;
- }
- rbd.setAutowireMode(getAutowireMode(autowire));
- // 设置 bean 的 init-method
- String initMethodName = ele.getAttribute(INIT_METHOD_ATTRIBUTE);
- if (!initMethodName.equals("")) {
- rbd.setInitMethodName(initMethodName);
- }
- // 设置 bean 的 destroy-method
- String destroyMethodName = ele.getAttribute(DESTROY_METHOD_ATTRIBUTE);
- if (!destroyMethodName.equals("")) {
- rbd.setDestroyMethodName(destroyMethodName);
- }
- bd = rbd;
- }
- else {
- bd = new ChildBeanDefinition(parent, pvs);
- }
- // 设置 bean 是否为单例
- if (ele.hasAttribute(SINGLETON_ATTRIBUTE)) {
- bd.setSingleton(TRUE_VALUE.equals(ele.getAttribute(SINGLETON_ATTRIBUTE)));
- }
- // 是否懒加载
- String lazyInit = ele.getAttribute(LAZY_INIT_ATTRIBUTE);
- if (DEFAULT_VALUE.equals(lazyInit) && bd.isSingleton()) {
- // just apply default to singletons, as lazy-init has no meaning for prototypes
- lazyInit = this.defaultLazyInit;
- }
- bd.setLazyInit(TRUE_VALUE.equals(lazyInit));
- bd.setResourceDescription(this.resource.getDescription());
- return bd;
- }
- catch (ClassNotFoundException ex) {
- }
- catch (NoClassDefFoundError err) {}
- }
Spring 容器在将配置文件加载后, 会解析 bean 标签并通过其相应的属性配置构造 BeanDefinition 对象, 然后将 BeanDefinition 对象注册添加到 BeanFactory 中.
Spring Bean 实例化
- public void preInstantiateSingletons() {
- if (logger.isInfoEnabled()) {
- logger.info("Pre-instantiating singletons in factory [" + this + "]");
- }
- // 遍历注册的 bean definition
- for (Iterator it = this.beanDefinitionNames.iterator(); it.hasNext();) {
- String beanName = (String) it.next();
- if (containsBeanDefinition(beanName)) {
- RootBeanDefinition bd = getMergedBeanDefinition(beanName, false);
- // 如果 bean 定义为单例且非延迟加载的
- if (bd.isSingleton() && !bd.isLazyInit()) {
- // 判断 bean 是否为 FactoryBean
- if (FactoryBean.class.isAssignableFrom(bd.getBeanClass())) {
- FactoryBean factory = (FactoryBean) getBean(FACTORY_BEAN_PREFIX + beanName);
- if (factory.isSingleton()) {
- getBean(beanName);
- }
- }
- else {
- // 若是普通 bean 则调用 getBean
- getBean(beanName);
- }
- }
- }
- }
- }
- public Object getBean(String name) throws BeansException {
- String beanName = transformedBeanName(name);
- // eagerly check singleton cache for manually registered singletons
- // 检查单例缓存池中 是否存在 bean 实例, 如果有从缓存中获取 bean 实例
- Object sharedInstance = this.singletonCache.get(beanName);
- if (sharedInstance != null) {
- if (logger.isDebugEnabled()) {
- logger.debug("Returning cached instance of singleton bean'" + beanName + "'");
- }
- return getObjectForSharedInstance(name, sharedInstance);
- }
- else {
- // check if bean definition exists
- RootBeanDefinition mergedBeanDefinition = null;
- try {
- mergedBeanDefinition = getMergedBeanDefinition(beanName, false);
- }
- catch (NoSuchBeanDefinitionException ex) {
- // not found -> check parent
- if (this.parentBeanFactory != null) {
- return this.parentBeanFactory.getBean(name);
- }
- throw ex;
- }
- // create bean instance
- if (mergedBeanDefinition.isSingleton()) {
- synchronized (this.singletonCache) {
- // re-check singleton cache within synchronized block
- sharedInstance = this.singletonCache.get(beanName);
- if (sharedInstance == null) {
- logger.info("Creating shared instance of singleton bean'" + beanName + "'");
- sharedInstance = createBean(beanName, mergedBeanDefinition);
- addSingleton(beanName, sharedInstance);
- }
- }
- return getObjectForSharedInstance(name, sharedInstance);
- }
- else {
- return createBean(name, mergedBeanDefinition);
- }
- }
- }
- protected Object createBean(String beanName, RootBeanDefinition mergedBeanDefinition) throws BeansException {
- if (mergedBeanDefinition.getDependsOn() != null) {
- for (int i = 0; i <mergedBeanDefinition.getDependsOn().length; i++) {
- // guarantee initialization of beans that the current one depends on
- getBean(mergedBeanDefinition.getDependsOn()[i]);
- }
- }
- // bean 初始化并包装, 也就是 new
- BeanWrapper instanceWrapper = null;
- if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
- mergedBeanDefinition.hasConstructorArgumentValues()) {
- instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
- }
- else {
- instanceWrapper = new BeanWrapperImpl(mergedBeanDefinition.getBeanClass());
- initBeanWrapper(instanceWrapper);
- }
- Object bean = instanceWrapper.getWrappedInstance();
- // Eagerly cache singletons to be able to resolve circular references
- // even when triggered by lifecycle interfaces like BeanFactoryAware.
- if (mergedBeanDefinition.isSingleton()) {
- // 单例的 bean 则添加到缓存中
- addSingleton(beanName, bean);
- }
- // bean 属性注入
- populateBean(beanName, mergedBeanDefinition, instanceWrapper);
- try {
- if (bean instanceof BeanNameAware) {
- // bean 若实现接口 BeanNameAware 则调用 setBeanName 方法
- ((BeanNameAware) bean).setBeanName(beanName);
- }
- if (bean instanceof BeanFactoryAware) {
- // bean 若实现接口 BeanFactoryAware 则调用 setBeanFactory 方法
- ((BeanFactoryAware) bean).setBeanFactory(this);
- }
- // 调用 BeanPostProcessor 执行 postProcessBeforeInitialization 方法
- bean = applyBeanPostProcessorsBeforeInitialization(bean, beanName);
- // 若 bean 实现 InitializingBean 接口则执行 afterPropertiesSet 方法
- // 若 bean 定义中定义了 init-method 属性则执行对应的 init 方法
- invokeInitMethods(bean, beanName, mergedBeanDefinition);
- // 调用 BeanPostProcessor 执行 postProcessAfterInitialization 方法
- bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
- }
- catch (InvocationTargetException ex) {
- throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
- "Initialization of bean failed", ex.getTargetException());
- }
- catch (Exception ex) {
- throw new BeanCreationException(mergedBeanDefinition.getResourceDescription(), beanName,
- "Initialization of bean failed", ex);
- }
- return bean;
- }
从 bean 的实例化过程中, Spring 容器在启动时只针对单例且非延迟加载的 bean 进行初始化; 其他的 bean 只有在显示调用 getBean() 方法时才去实例化; 下面将会对实例化过程中的详细过程进行说明.
Spring Bean 作用域
singleton 单例模式
Spring IoC 容器中只会存在一个共享的 Bean 实例, 无论有多少个 Bean 引用它, 始终指向同一对象.
- <bean id="test" singleton="true" />
- <bean scope="singleton" />
Spring 1.0 中通过 bean 定义属性 singleton='true' 表示单例; 在 Spring 2.x 之后版本改为定义属性 scope='singleton', 同时兼容 1.0 的配置
prototype 原型模式
每次通过 Spring 容器获取 prototype 定义的 bean 时, 容器都将创建一个新的 Bean 实例, 每个 Bean 实例都有自己的属性和状态
- <bean id="test" singleton="false" />
- <bean scope="prototype" />
Spring 1.0 中通过 bean 定义属性 singleton='false' 表示原型模式; 在 Spring 2.x 之后版本改为定义属性 scope='prototype', 同时兼容 1.0 的配置
Spring Bean 生命周期
image
示例
- public class LifecycleBean implements BeanNameAware, InitializingBean, BeanFactoryAware, ResourceLoaderAware, ApplicationContextAware, DisposableBean {
- public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
- System.out.println("set bean factory");
- }
- public void setBeanName(String name) {
- System.out.println("set bean name");
- }
- public void afterPropertiesSet() throws Exception {
- System.out.println("Initializing Bean afterPropertiesSet");
- }
- public void setApplicationContext(ApplicationContext context) throws BeansException {
- System.out.println("set application context");
- }
- public void setResourceLoader(ResourceLoader resourceLoader) {
- System.out.println("set resource loader");
- }
- public void init () {
- System.out.println("do init method");
- }
- public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
- System.out.println("post Process Before Initialization");
- return bean;
- }
- public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
- System.out.println("post Process After Initialization");
- return bean;
- }
- public void destroy() throws Exception {
- System.out.println("do destroy");
- }
- public void destroyMethod() throws Exception {
- System.out.println("do destroy method");
- }
- }
- public class PostProcessor implements BeanPostProcessor {
- public Object postProcessBeforeInitialization(Object bean, String name) throws BeansException {
- if (bean instanceof LifecycleBean) {
- ((LifecycleBean) bean).postProcessBeforeInitialization(bean, name);
- }
- return bean;
- }
- public Object postProcessAfterInitialization(Object bean, String name) throws BeansException {
- if (bean instanceof LifecycleBean) {
- ((LifecycleBean) bean).postProcessAfterInitialization(bean, name);
- }
- return bean;
- }
- }
spring 配置文件如下
- <beans>
- <bean id="lifecycleBean" class="org.springframework.beans.factory.LifecycleBean" init-method="init" />
- <bean id="postProcessor" class="org.springframework.beans.factory.PostProcessor" />
- </beans>
运行结果如下:
- set bean name
- set bean factory
- set resource loader
- set application context
- post Process Before Initialization
- Initializing Bean afterPropertiesSet
- do init method
- post Process After Initialization
- do destroy
- do destroy method
Spring Bean 注入方式
构造注入
- <bean>
- <constructor-arg index="1">
- <value></value>
- </constructor-arg>
- </bean>
- <bean autowire="constructor" />
当 bean 定义配置如以上方式的时候, 会触发 autowireConstructor (详细实现参考源码吧)
- BeanWrapper instanceWrapper = null;
- if (mergedBeanDefinition.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
- mergedBeanDefinition.hasConstructorArgumentValues()) {
- instanceWrapper = autowireConstructor(beanName, mergedBeanDefinition);
- }
byType 注入
<bean autowire="byType" />
当 bean 定义配置如以上方式的时候, 会触发 autowireByType 如下:
- protected void autowireByType(String beanName, RootBeanDefinition mergedBeanDefinition,
- BeanWrapper bw, MutablePropertyValues pvs) {
- // 查找 bean 存在可写方法的非基本数据类型的成员变量
- String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
- for (int i = 0; i <propertyNames.length; i++) {
- String propertyName = propertyNames[i];
- // look for a matching type
- // 获取成员变量的类型
- Class requiredType = bw.getPropertyDescriptor(propertyName).getPropertyType();
- // 查找成员变量对应的 bean 实例
- Map matchingBeans = findMatchingBeans(requiredType);
- if (matchingBeans != null && matchingBeans.size() == 1) {
- // 成员变量查找到匹配的 bean 实例, 有且只有一个的时候
- // 将属性名和属性值 添加到 PropertyValues 中
- pvs.addPropertyValue(propertyName, matchingBeans.values().iterator().next());
- if (logger.isDebugEnabled()) {
- logger.debug("Autowiring by type from bean name'" + beanName +
- "'via property'" + propertyName + "'to bean named'" +
- matchingBeans.keySet().iterator().next() + "'");
- }
- }
- else if (matchingBeans != null && matchingBeans.size()> 1) {
- // 当存在多个同类型的实例时 抛出异常
- throw new UnsatisfiedDependencyException(beanName, propertyName,
- "There are" + matchingBeans.size() + "beans of type [" + requiredType + "] for autowire by type." +
- "There should have been 1 to be able to autowire property'" + propertyName + "'of bean'" + beanName + "'.");
- }
- else {
- if (logger.isDebugEnabled()) {
- logger.debug("Not autowiring property'" + propertyName + "'of bean'" + beanName +
- "'by type: no matching bean found");
- }
- }
- }
- }
byName 注入
<bean autowire="byName" />
当 bean 定义配置如以上方式的时候, 会触发 autowireByName 如下:
- protected void autowireByName(String beanName, RootBeanDefinition mergedBeanDefinition,
- BeanWrapper bw, MutablePropertyValues pvs) {
- // 查找 bean 存在可写方法的非基本数据类型的成员变量
- String[] propertyNames = unsatisfiedObjectProperties(mergedBeanDefinition, bw);
- for (int i = 0; i <propertyNames.length; i++) {
- String propertyName = propertyNames[i];
- // 在 Spring 容器中查找是否存在以 propertyName 命名的 bean definition
- if (containsBean(propertyName)) {
- // 实例化依赖的 bean, 并添加到 MutablePropertyValues 中
- Object bean = getBean(propertyName);
- pvs.addPropertyValue(propertyName, bean);
- if (logger.isDebugEnabled()) {
- logger.debug("Added autowiring by name from bean name'" + beanName +
- "'via property'" + propertyName + "'to bean named'" + propertyName + "'");
- }
- }
- else {
- if (logger.isDebugEnabled()) {
- logger.debug("Not autowiring property'" + propertyName + "'of bean'" + beanName +
- "'by name: no matching bean found");
- }
- }
- }
- }
set 注入
- <bean>
- <property name="age">
- <value>11</value>
- </property>
- </bean>
当 bean 定义配置如上, 或者采用 byName, byType 的注入方式时, 都会调用 applyPropertyValues 方法完成属性的注入.(详细实现参考源码吧)
Spring Bean 注解式注入
自 Spring 2.5 版本之后, 支持通过注解方式实现 Bean 的自动注入, 譬如 @Autowired, @Resource 等注解
为了引入注解式自动注入, Spring 在 2.x 版本中新增了 InstantiationAwareBeanPostProcessor 接口, 该接口继承 BeanPostProcessor 并新增了方法 postProcessPropertyValues ; 该方法主要实现
Post-process the given property values before the factory applies them to the given bean
Autowired 注解
采用 Autowired 注解实现自动注入, 需在配置文件中配置 AutowiredAnnotationBeanPostProcessor Bean
- public AutowiredAnnotationBeanPostProcessor() {
- this.autowiredAnnotationTypes.add(Autowired.class);
- this.autowiredAnnotationTypes.add(Value.class);
- ClassLoader cl = AutowiredAnnotationBeanPostProcessor.class.getClassLoader();
- try {
- this.autowiredAnnotationTypes.add((Class<? extends Annotation>) cl.loadClass("javax.inject.Inject"));
- logger.info("JSR-330'javax.inject.Inject'annotation found and supported for autowiring");
- }
- catch (ClassNotFoundException ex) {
- // JSR-330 API not available - simply skip.
- }
- }
从 AutowiredAnnotationBeanPostProcessor 构造可以看出其支持 @Autowired,@Value,@Inject 注解的自动注入. 下面大概看下其如何实现自动注入
- public PropertyValues postProcessPropertyValues(
- PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
- // 查找 bean 中需要自动注入的元数据, 包括 field, method
- InjectionMetadata metadata = findAutowiringMetadata(bean.getClass());
- try {
- // 实现注入
- metadata.inject(bean, beanName, pvs);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);
- }
- return pvs;
- }
Resource 注解
采用 Resource 注解实现自动注入, 需在配置文件中配置 CommonAnnotationBeanPostProcessor Bean
- public CommonAnnotationBeanPostProcessor() {
- setOrder(Ordered.LOWEST_PRECEDENCE - 3);
- setInitAnnotationType(PostConstruct.class);
- setDestroyAnnotationType(PreDestroy.class);
- ignoreResourceType("javax.xml.ws.WebServiceContext");
- }
从 CommonAnnotationBeanPostProcessor 构造可以看出, 该类同时支持对注解 @PostConstruct, @PreDestroy 生效.
- public PropertyValues postProcessPropertyValues(
- PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
- // 查找 bean 中标注有 @Resource 注解的 Field, method
- InjectionMetadata metadata = findResourceMetadata(bean.getClass());
- try {
- // 实现注入
- metadata.inject(bean, beanName, pvs);
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
- }
- return pvs;
- }
- public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
- // 查找 bean 定义中标注了 PostConstruct 注解的方法
- LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
- try {
- // 调用指定 post construct method
- metadata.invokeInitMethods(bean, beanName);
- }
- catch (InvocationTargetException ex) {
- throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
- }
- catch (Throwable ex) {
- throw new BeanCreationException(beanName, "Couldn't invoke init method", ex);
- }
- return bean;
- }
- public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
- // 查找 bean 定义中标注了 PreDestroy 注解的方法
- LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
- try {
- // 调用指定 destroy method
- metadata.invokeDestroyMethods(bean, beanName);
- }
- catch (InvocationTargetException ex) {
- String msg = "Invocation of destroy method failed on bean with name'" + beanName + "'";
- if (logger.isDebugEnabled()) {
- logger.warn(msg, ex.getTargetException());
- }
- else {
- logger.warn(msg + ":" + ex.getTargetException());
- }
- }
- catch (Throwable ex) {
- logger.error("Couldn't invoke destroy method on bean with name '"+ beanName +"'", ex);
- }
- }
- private LifecycleMetadata buildLifecycleMetadata(Class clazz) {
- final boolean debug = logger.isDebugEnabled();
- LinkedList<LifecycleElement> initMethods = new LinkedList<LifecycleElement>();
- LinkedList<LifecycleElement> destroyMethods = new LinkedList<LifecycleElement>();
- Class<?> targetClass = clazz;
- do {
- LinkedList<LifecycleElement> currInitMethods = new LinkedList<LifecycleElement>();
- LinkedList<LifecycleElement> currDestroyMethods = new LinkedList<LifecycleElement>();
- // 遍历 bean 的所有方法
- for (Method method : targetClass.getDeclaredMethods()) {
- if (this.initAnnotationType != null) {
- // 判断 method 是否标注了 @PostConstruct 注解
- if (method.getAnnotation(this.initAnnotationType) != null) {
- LifecycleElement element = new LifecycleElement(method);
- currInitMethods.add(element);
- if (debug) {
- logger.debug("Found init method on class [" + clazz.getName() + "]:" + method);
- }
- }
- }
- if (this.destroyAnnotationType != null) {
- // 判断 method 是否标注了 @PreDestroy 注解
- if (method.getAnnotation(this.destroyAnnotationType) != null) {
- currDestroyMethods.add(new LifecycleElement(method));
- if (debug) {
- logger.debug("Found destroy method on class [" + clazz.getName() + "]:" + method);
- }
- }
- }
- }
- initMethods.addAll(0, currInitMethods);
- destroyMethods.addAll(currDestroyMethods);
- targetClass = targetClass.getSuperclass();
- }
- while (targetClass != null && targetClass != Object.class);
- return new LifecycleMetadata(clazz, initMethods, destroyMethods);
- }
- <context: annotation-config>
为了简化 Spring 配置文件中的 bean 配置, Spring 提供了 <context: annotation-config> 标签自动加载 AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor 等 bean.
在 spring-context 包 resources/META-INF 下的 spring.handlers 文件中配置如下:
- http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
- public class ContextNamespaceHandler extends NamespaceHandlerSupport {
- public void init() {
- registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
- registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
- registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
- registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
- registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
- registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
- registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
- registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
- }
- }
- public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
- BeanDefinitionRegistry registry, Object source) {
- Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<BeanDefinitionHolder>(4);
- if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- // 加载注册 AutowiredAnnotationBeanPostProcessor
- RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- // 加载注册 RequiredAnnotationBeanPostProcessor
- RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
- if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- // 加载注册 CommonAnnotationBeanPostProcessor
- RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
- if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
- RootBeanDefinition def = new RootBeanDefinition();
- try {
- ClassLoader cl = AnnotationConfigUtils.class.getClassLoader();
- def.setBeanClass(cl.loadClass(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME));
- }
- catch (ClassNotFoundException ex) {
- throw new IllegalStateException(
- "Cannot load optional framework class:" + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
- }
- def.setSource(source);
- beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
- }
- return beanDefs;
- }
可以看出在 Spring 启动时, 通过解析 <context: annotation-config> 标签, 完成对 CommonAnnotationBeanPostProcessor, AutowiredAnnotationBeanPostProcessor 的加载注册, 进而实现通过注解方式的自动注入.
小结
BeanFactory & ApplicationContext
image
- BeanFactoryPostProcessor & BeanPostProcessor
- BeanFactoryPostProcessor
是 ApplicationContext 在 BeanFactory 完成创建后对其进行后置处理的接口
BeanPostProcessor 是 BeanFactory 在 Bean 完成实例化对其进行的后置处理接口
BeanFactory & FactoryBean
BeanFactory 是 Spring 框架底层的核心接口, 其提供了创建 bean, 获取 bean 等核心功能.
FactoryBean 是生产 bean 的一个模式, 也就是以工厂模式的方式生产 bean.
来源: http://www.jianshu.com/p/b1f3e8ba4bfd