前言

前段时间直接上手使用springboot开发了一个数据平台的后台部分,但是自身对于springboot的原理和过程还不是很清晰,所以反过来学习下springboot的基础。

大家都知道springboot是基于注解的,IOC和AOP是它的两大重要特性,然后AOP又是基于IOC来实现的。那么弄懂IOC就很有必要了。

IOC:控制反转,一种设计思想,它是Spring的核心。简单点说就是spring管理bean的容器。IOC容器一般具备两个基本功能:

  1、通过描述管理Bean,包括发布和获取。

  2、描述Bean之间的依赖关系。这两个问题深究下去是没有边界的,尤其是Bean之间的依赖关系,这个就是spring的核心。

从IOC的概念和功能就引申出了一个重要概念: Bean 

本文将全方位介绍Spring Bean的生命周期

Spring Bean的简要流程:

如上图所示,在XML或者其他文件定义bean之后,spring通过注解的方式将bean传递到IOC容器,IOC容器将bean注册后给类class调用并实例化-构建,之后将bean放入到容器的缓冲池供程序调用。

从图片可以看到Spring Bean 在整个SpringBoot 项目中至关重要,它经过的路径如下:

  1. 实例化  【IOC容器寻找Bean的定义信息并将其实例化】
  2. 设置bean的Aware 【Aware意指能提前感知的,是spring的一个重要接口,使用依赖注入,spring按照Bean定义信息配置Bean的所有属性】
  3. BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName)   【如果BeanPostProcessor和Bean关联,那么其postProcessBeforeInitialization()方法将被调用,Spring 框架会遍历得到容器中所有的 BeanPostProcessor ,挨个执行】
  4. InitializingBean.afterPorpertiesSet     【初始化bean, springboot读取properties文件的过程,默认的application.properties 还有其他方式】
  5. BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName)  【如果有BeanPostProcessor和Bean关联,那么其postProcessAfterInitialization()方法将被调用】
  6. SmartInitializingSingleton.afterSingletonsInstantiated
  7. SmartLifecycle.start
  8. 运行Bean
  9. SmartLifecycle.stop(Runnable callback)     
  10. DisposableBean.destroy()     【销毁】

详细解释

1.实例化对应代码

  【使用合适的初始化方案来创建一个新的bean实例,factory-method,构造器注入或者简单的直接实例化

  实例化策略类:
    InstantiationStrategy

  实例化具体方法:
    AbstractAutowireCapableBeanFactory.createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args)

  

  构造器注入:

    @CompnentScan 【启动类】查找beans,结合@Autowired构造注入【Service层】

  

  Factory Mothod方式也分两种, 分别是静态工厂方法 和 实例工厂方法。

   1. 先创建一个汽车car类 

public class Car {
private int id;
private String name;
private int price; public int getId() {
return id;
} public void setId(int id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public int getPrice() {
return price;
} public void setPrice(int price) {
this.price = price;
} @Override
public String toString() {
return "Car [id=" + id + ", name=" + name + ", price=" + price + "]";
} public Car(){ } public Car(int id, String name, int price) {
super();
this.id = id;
this.name = name;
this.price = price;
}
}

      2. 定义一个工厂类 (定义了1个静态的bean 容器map. 然后提供1个静态方法根据Car 的id 来获取容器里的car对象。)

import java.util.HashMap;
import java.util.Map; public class CarStaticFactory {
private static Map<Integer, Car> map = new HashMap<Integer,Car>(); static{
map.put(1, new Car(1,"Honda",300000));
map.put(2, new Car(2,"Audi",440000));
map.put(3, new Car(3,"BMW",540000));
} public static Car getCar(int id){
return map.get(id);
} }

3. 定义配置XML (利用静态工厂方法定义的bean item种, class属性不在是bean的全类名, 而是静态工厂的全类名, 而且还需要指定工厂里的getBean 静态方法名字和参数)

  <!--
Static Factory method:
class: the class of Factory
factory-method: method of get Bean Object
constructor-arg: parameters of factory-method
-->
<bean id="bmwCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar">
<constructor-arg value="3"></constructor-arg>
</bean> <bean id="audiCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar">
<constructor-arg value="2"></constructor-arg>
</bean>

     4. 客户端调用factory-method的bean

public static void h(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean-factoryMethod.xml");
Car car1 = (Car) ctx.getBean("bmwCar");
System.out.println(car1); car1 = (Car) ctx.getBean("audiCar");
System.out.println(car1);
}

  

2.设置bean的Aware

  【InitializingBean.afterPorpertiesSet,BeanPostProcessor对bean的加工处理基本上在一块出现。】

  设置Aware方法顺序:

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware

  BeanPostProcessor.postProcessBeforeInitialization

  ApplicationContextAwareProcessor也会设置Aware:

  • EnvironmentAware
  • EmbeddedValueResolverAware
  • ResourceLoaderAware
  • ApplicationEventPublisherAware
  • MessageSourceAware
  • ApplicationContextAware

调用afterpropertiesSet方法:位于AbstractAutowireCapableBeanFactory.invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)方法中

源码:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {

      // 设置Aware
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
invokeAwareMethods(beanName, bean);
return null;
}
}, getAccessControlContext());
}
else {
invokeAwareMethods(beanName, bean);
} //BeanPostProcessor的postProcessBeforeInitialization
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
} try {
//调用init方法,其判断是否是InitializingBean的实例,然后调用afterPropertiesSet
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
} //BeanPostProcessor的postProcessAfterInitialization
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}

3. SmartInitializingSingleton.afterSingletonsInstantiated的调用位置

  【DefaultListableBeanFactory.preInstantiateSingletons方法,其在所有的bean都实例化完成之后调用】
 
  源码:
@Override
public void preInstantiateSingletons() throws BeansException {
if (this.logger.isDebugEnabled()) {
this.logger.debug("Pre-instantiating singletons in " + this);
} // Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans...
// 触发实例化所有的非懒加载的单例
for (String beanName : beanNames) {
...
} // Trigger post-initialization callback for all applicable beans...
// 触发应用bean的post-initialization回调,也就是afterSingletonsInstantiated方法
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}

4. SmartLifecycle.start

  在ApplicationContext结束刷新finishRefresh时,getLifecycleProcessor().onRefresh();

  判断bean是否为SmartLifecycle并且autoStartup。

  位于:
  DefaultLifecycleProcessor.onRefresh

5. stop方法

  在Application.close的时候,调用getLifecycleProcessor().stop()方法仍然在DefaultLifecycleProcessor内部

6. DisposableBean.destroy方法

  doCreateBean方法中会判断bean是否有销毁相关操作,实现了DisposableBean方法或定义了销毁方法。

  AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)

7. Bean 生命周期演示代码以及运行结果

public class HelloWorld implements SmartInitializingSingleton,SmartLifecycle,InitializingBean,
DisposableBean,MyInterface,BeanNameAware,ApplicationContextAware
{ private final Log logger = LogFactory.getLog(getClass());
private boolean isRunning; public HelloWorld() {
System.out.println("实例化");
} public void sayHello(){
System.out.println("hello World");
} public void afterSingletonsInstantiated() {
System.out.println("SmartInitializingSingleton afterSingletonsInstantiated");
} public void start() {
isRunning = true;
System.out.println("LifeCycle start");
} public void stop() {
System.out.println("LifeCycle stop");
} public boolean isRunning() {
return isRunning;
} public boolean isAutoStartup() {
return true;
} public void stop(Runnable callback) {
System.out.println("LifeScycle stop");
callback.run();
} public int getPhase() {
return 0;
} public void afterPropertiesSet() throws Exception {
System.out.println("afterproperties set");
} public void destroy() throws Exception {
System.out.println("destroy");
} public void my(String str) {
System.out.println(str);
} public void setBeanName(String name) {
System.out.println("set bean Name aware");
} public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("set Application Aware");
}
} //MyInterface接口
public interface MyInterface {
void my(String str);
} //app.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="porcessor" class="me.aihe.MyBeanPostProcessor" />
<bean id="hello" class="me.aihe.HelloWorld"> </bean>
</beans> //SpringApp
public class SpringApp {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
HelloWorld hello = (HelloWorld) applicationContext.getBean("hello");
hello.sayHello();
applicationContext.close();
}
}

总结:

Spring Bean  是整个Spring的基石,意义不言而喻,通过bean可以获取对象,实现容器,反射,简化配置,中间件,线程池等等。所以学习它非常有必要。

最新文章

  1. 面向组合子设计Coder
  2. System.map文件【转】
  3. C++ 随机数
  4. Cassandra中的数据一致性
  5. iOS 真机文件系统区分大小写,而模拟器可能不区分
  6. 【C++】array初始化0
  7. leetcode 145. Binary Tree Postorder Traversal ----- java
  8. Add LUN to ASM in Linux
  9. github -- fork提交项目
  10. 十、Socket之UDP编程
  11. Android中的多媒体显示之图片缩放
  12. 什么是DNN,Dotnetnuke介绍和功能简介
  13. 字符串-06. IP地址转换(20)
  14. ShaderLab 之 UNITY_INITIALIZE_OUTPUT
  15. Docker+Gogs搭建个人Git服务
  16. JAVA基础-反射
  17. vue-cli 使用小技巧
  18. python 列表解析与map和filter函数
  19. python 基础语法梳理
  20. windows安装zookeeper

热门文章

  1. Pair Testing
  2. 实现自己的DiscoveryClient
  3. bfs(最短路径)
  4. 洛谷 - P3803 - 【模板】多项式乘法(FFT) - FFT
  5. javascript判断chrome浏览器的方法
  6. NGUI的widget的使用
  7. day65--mysql数据库--索引、慢日志、分页
  8. Solr的学习使用之(二)schema.xml等配置文件的解析
  9. Android线程间通信的几种实现方式
  10. shell命令结果重定向