前言
前段時間直接上手使用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 項目中至關重要,它經過的路徑如下:
- 實例化 【IOC容器尋找Bean的定義信息並將其實例化】
- 設置bean的Aware 【Aware意指能提前感知的,是spring的一個重要接口,使用依賴注入,spring按照Bean定義信息配置Bean的所有屬性】
- BeanPostProcessor.postProcessBeforeInitialization(Object bean, String beanName) 【如果BeanPostProcessor和Bean關聯,那么其postProcessBeforeInitialization()方法將被調用,Spring 框架會遍歷得到容器中所有的 BeanPostProcessor ,挨個執行】
- InitializingBean.afterPorpertiesSet 【初始化bean, springboot讀取properties文件的過程,默認的application.properties 還有其他方式】
- BeanPostProcessor.postProcessAfterInitialization(Object bean, String beanName) 【如果有BeanPostProcessor和Bean關聯,那么其postProcessAfterInitialization()方法將被調用】
- SmartInitializingSingleton.afterSingletonsInstantiated
- SmartLifecycle.start
- 運行Bean
- SmartLifecycle.stop(Runnable callback)
- 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的調用位置

@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可以獲取對象,實現容器,反射,簡化配置,中間件,線程池等等。所以學習它非常有必要。