我们知道,在spring bean生命周期中,我们可以在不同阶段执行处理器或者方法,比如init-method,destroy方法,BeanPostProcessor接口等。那么这些处理器或方法的执行顺序是怎样的,让我们用实际例子来观察。

package com.coshaho.learn.spring;

import java.util.HashMap;
import java.util.Map; import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.DependsOn;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component; /**
*
* ASpringProcessor.java Create on 2017年10月17日 下午10:06:35
*
* 类功能说明: Spring处理器执行顺序
*
* Copyright: Copyright(c) 2013
* Company: COSHAHO
* @Version 1.0
* @Author coshaho
*/
@Component("springProcessor")
@DependsOn("dependsBean")
@ComponentScan("com.coshaho.learn.spring")
public class ASpringProcessor implements InitializingBean, DisposableBean, BeanNameAware
{
@Autowired
public BAutowiredBean autowiredBean; public ASpringProcessor()
{
System.out.println("SpringProcessor construct. x is " + x + ".");
} // BeanNameAware
public void setBeanName(String name)
{
System.out.println("Call BeanNameAware setBeanName, name is " + name + ", x is " + x + ".");
} // DisposableBean
public void destroy() throws Exception
{
System.out.println("Call DisposableBean destroy.");
} // InitializingBean
public void afterPropertiesSet() throws Exception
{
System.out.println("Call InitializingBean afterPropertiesSet.");
} @PostConstruct
public void postConstruct()
{
System.out.println("Call postConstruct method.");
} @PreDestroy
public void preDestroy()
{
System.out.println("Call preDestroy method.");
} public void initMethod()
{
System.out.println("Call manually initMethod.");
} public void destroyMethod()
{
System.out.println("Call manually destroyMethod.");
} public void sayHello()
{
System.out.println("Hello, Spring.");
} @Value("cauchy")
private String x;
public void setX(String x)
{
this.x = x;
} public static void main(String[] args) throws Exception
{
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring.xml");
ASpringProcessor springBean = (ASpringProcessor)context.getBean("springProcessor");
springBean.sayHello();
context.close(); System.out.println(); // 创建一个BeanFactory
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.addBeanPostProcessor(new EBeanPostProcessor()); // 构造一个BeanDefinition
AnnotatedGenericBeanDefinition beanDefinition=new AnnotatedGenericBeanDefinition(ASpringProcessor.class);
beanDefinition.setInitMethodName("initMethod");
beanDefinition.setDestroyMethodName("destroyMethod"); // 设置这个bean的属性
Map<String, Object> map = new HashMap<String, Object>();
map.put("x", "coshaho");
beanDefinition.setPropertyValues(new MutablePropertyValues(map)); // 注册BeanDefinition
factory.registerBeanDefinition("springProcessor", beanDefinition); // 执行获取和销毁bean的方法
factory.getBean("springProcessor");
factory.destroySingleton("springProcessor");
}
} package com.coshaho.learn.spring; import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor; class EBeanPostProcessor implements BeanPostProcessor
{
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException
{
System.out.println("MyBeanPostProcessor postProcessBeforeInitialization.");
return bean;
} public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException
{
System.out.println("MyBeanPostProcessor postProcessAfterInitialization.");
return bean;
}
}
package com.coshaho.learn.spring;

import org.springframework.stereotype.Service;

@Service
public class BAutowiredBean
{
public BAutowiredBean()
{
System.out.println("AutowiredBean construct.");
} } package com.coshaho.learn.spring; import org.springframework.stereotype.Service; @Service("dependsBean")
public class CDependsBean
{
public CDependsBean()
{
System.out.println("DependsBean construct.");
} }

执行结果

Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@7cef4e59: startup date [Tue Oct 17 18:18:23 GMT+08:00 2017]; root of context hierarchy
Loading XML bean definitions from class path resource [spring.xml]
DependsBean construct.
SpringProcessor construct. x is null.
AutowiredBean construct.
Call BeanNameAware setBeanName, name is springProcessor, x is cauchy.
Call postConstruct method.
Call InitializingBean afterPropertiesSet.
Hello, Spring.
Closing org.springframework.context.support.ClassPathXmlApplicationContext@7cef4e59: startup date [Tue Oct 17 18:18:23 GMT+08:00 2017]; root of context hierarchy
Call preDestroy method.
Call DisposableBean destroy. SpringProcessor construct. x is null.
Call BeanNameAware setBeanName, name is springProcessor, x is coshaho.
MyBeanPostProcessor postProcessBeforeInitialization.
Call InitializingBean afterPropertiesSet.
Call manually initMethod.
MyBeanPostProcessor postProcessAfterInitialization.
Call DisposableBean destroy.
Call manually destroyMethod.

可以看出来,spring bean加载顺序如下

1. 初始化depends bean;

2. 执行bean构造方法;

3. 初始化依赖注入bean;

4. 其他属性赋值;

5. 执行BeanNameAware接口的setBeanName方法;

6. 执行BeanPostProcessor接口postProcessBeforeInitialization方法;

7. 执行@PostConstruct注解方法;

8. 执行InitializingBean接口的afterPropertiesSet方法;

9. 执行init-method方法;

10. 执行BeanPostProcessor接口postProcessAfterInitialization方法;

11. 执行@PreDestroy注解方法;

12. 执行DisposableBean接口的destroy方法;

13. 执行destroy-method方法。

Spring源码阅读(四)的更多相关文章

  1. 40 网络相关函数(八)——live555源码阅读(四)网络

    40 网络相关函数(八)——live555源码阅读(四)网络 40 网络相关函数(八)——live555源码阅读(四)网络 简介 15)writeSocket向套接口写数据 TTL的概念 函数send ...

  2. 39 网络相关函数(七)——live555源码阅读(四)网络

    39 网络相关函数(七)——live555源码阅读(四)网络 39 网络相关函数(七)——live555源码阅读(四)网络 简介 14)readSocket从套接口读取数据 recv/recvfrom ...

  3. 38 网络相关函数(六)——live555源码阅读(四)网络

    38 网络相关函数(六)——live555源码阅读(四)网络 38 网络相关函数(六)——live555源码阅读(四)网络 简介 12)makeSocketNonBlocking和makeSocket ...

  4. 37 网络相关函数(五)——live555源码阅读(四)网络

    37 网络相关函数(五)——live555源码阅读(四)网络 37 网络相关函数(五)——live555源码阅读(四)网络 简介 10)MAKE_SOCKADDR_IN构建sockaddr_in结构体 ...

  5. 36 网络相关函数(四)——live555源码阅读(四)网络

    36 网络相关函数(四)——live555源码阅读(四)网络 36 网络相关函数(四)——live555源码阅读(四)网络 简介 7)createSocket创建socket方法 8)closeSoc ...

  6. 35 网络相关函数(三)——live555源码阅读(四)网络

    35 网络相关函数(三)——live555源码阅读(四)网络 35 网络相关函数(三)——live555源码阅读(四)网络 简介 5)NoReuse不重用地址类 6)initializeWinsock ...

  7. 34 网络相关函数(二)——live555源码阅读(四)网络

    34 网络相关函数(二)——live555源码阅读(四)网络 34 网络相关函数(二)——live555源码阅读(四)网络 2)socketErr 套接口错误 3)groupsockPriv函数 4) ...

  8. 33 网络相关函数(一)——live555源码阅读(四)网络

    33 网络相关函数(一)——live555源码阅读(四)网络 33 网络相关函数(一)——live555源码阅读(四)网络 简介 1)IsMulticastAddress多播(组播)地址判断函数 多播 ...

  9. 32 GroupSock(AddressPortLookupTable)——live555源码阅读(四)网络

    32 GroupSock(AddressPortLookupTable)——live555源码阅读(四)网络 32 GroupSock(AddressPortLookupTable)——live555 ...

  10. 31 GroupSock(AddressString)——live555源码阅读(四)网络

    31 GroupSock(AddressString)——live555源码阅读(四)网络 31 GroupSock(AddressString)——live555源码阅读(四)网络 简介 Addre ...

随机推荐

  1. 【数据可视化-pyecharts】pyecharts快速入门

    pyecharts快速开始 首先开始来绘制你的第一个图表 from pyecharts import Bar bar = Bar("我的第一个图表", "这里是副标题&q ...

  2. Postfix 邮件服务器搭建

    搭建服务环境: Centos 6 配置域名hosts: mail.demonC6.com 1.清理系统自带的邮件软件 # rpm -qa | grep sendmail* # rpm -e sendm ...

  3. Got timeout reading communication packets解决方法

    Got timeout reading communication packets解决方法 http://www.th7.cn/db/mysql/201702/225243.shtml [Note] ...

  4. Unity-音频系统

    1.声音格式: WAV:无损,音质好,文件大,适用于短文件 OGG&&MP3: 有损,文件小,适用于较长文件,比如背景音乐

  5. Unity3D加密保护案例分享(一)

    Unity3D是由Unity Technologies开发的一个让玩家轻松创建诸如三维视频游戏.建筑可视化.实时三维动画等类型互动内容的多平台的综合型游戏开发工具,是一个全面整合的专业游戏引擎.通过u ...

  6. 小程序 input 键盘弹出时样式遮盖问题

    设置cursor-spacing,具体可参考官方文档,代码如下: <input type='text' bindinput="bindKeyInput"  placehold ...

  7. Centos7 zookeeper单机/集群安装详解和开机自启

    ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件.它是一个为分布式应用提供一致性服务的软件,提供的功 ...

  8. Windows本机搭建Redis

    1 下载安装包 GIT:https://github.com/MicrosoftArchive/redis/releases       Redis-x64-3.2.100.zip 百度网盘 :链接: ...

  9. (转)RBAC权限表的设计

    RBAC(Role-Based Access Control,基于角色的访问控制),就是用户通过角色与权限进行关联.简单地说,一个用户拥有若干角色,每一个角色拥有若干权限.这样,就构造成“用户-角色- ...

  10. Elasticsearch 搜索模块之Cross Cluster Search(跨集群搜索)

    Cross Cluster Search简介 cross-cluster search功能允许任何节点作为跨多个群集的federated client(联合客户端),与tribe node不同的是cr ...