前段時間直接上手使用springboot開發了一個數據平臺的後臺部分,可是自身對於springboot的原理和過程還不是很清晰,因此反過來學習下springboot的基礎。java
你們都知道springboot是基於註解的,IOC和AOP是它的兩大重要特性,而後AOP又是基於IOC來實現的。那麼弄懂IOC就頗有必要了。spring
IOC:控制反轉,一種設計思想,它是Spring的核心。簡單點說就是spring管理bean的容器。IOC容器通常具有兩個基本功能:bootstrap
一、經過描述管理Bean,包括髮布和獲取。springboot
二、描述Bean之間的依賴關係。這兩個問題深究下去是沒有邊界的,尤爲是Bean之間的依賴關係,這個就是spring的核心。app
從IOC的概念和功能就引伸出了一個重要概念: Bean 框架
本文將全方位介紹Spring Bean的生命週期ide
如上圖所示,在XML或者其餘文件定義bean以後,spring經過註解的方式將bean傳遞到IOC容器,IOC容器將bean註冊後給類class調用並實例化-構建,以後將bean放入到容器的緩衝池供程序調用。post
從圖片能夠看到Spring Bean 在整個SpringBoot 項目中相當重要,它通過的路徑以下:學習
【使用合適的初始化方案來建立一個新的bean實例,factory-method,構造器注入或者簡單的直接實例化】this
實例化策略類:
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); }
【InitializingBean.afterPorpertiesSet,BeanPostProcessor對bean的加工處理基本上在一塊出現。】
設置Aware方法順序:
BeanPostProcessor.postProcessBeforeInitialization
ApplicationContextAwareProcessor也會設置Aware:
調用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; }
@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(); } } } }
在ApplicationContext結束刷新finishRefresh時,getLifecycleProcessor().onRefresh();
判斷bean是否爲SmartLifecycle而且autoStartup。
位於:
DefaultLifecycleProcessor.onRefresh
在Application.close的時候,調用getLifecycleProcessor().stop()方法仍然在DefaultLifecycleProcessor內部
doCreateBean方法中會判斷bean是否有銷燬相關操做,實現了DisposableBean方法或定義了銷燬方法。
AbstractAutowireCapableBeanFactory.doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
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能夠獲取對象,實現容器,反射,簡化配置,中間件,線程池等等。因此學習它很是有必要。