您的位置:首页 > 编程语言 > Java开发

Spring源码阅读(四)

2017-10-17 22:31 302 查看
我们知道,在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方法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: