从源码了解spring bean实例化过程
我們先來看下spring如何手動初始化一個對象
ClassPathResource res = new ClassPathResource("beans.xml"); DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(res); User user=(User) factory.getBean("user"); 復制代碼所以我們先從DefaultListableBeanFactory開始了解 AbstractBeanFactory
public <T> T getBean(String name, Class<T> requiredType, Object... args) throws BeansException {return doGetBean(name, requiredType, args, false);} 復制代碼 protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {復制代碼1.去掉&
final String beanName = transformedBeanName(name); 復制代碼 protected String transformedBeanName(String name) {return canonicalName(BeanFactoryUtils.transformedBeanName(name));} 復制代碼2.如果是單例且存在,就直接取過來
Object bean;// Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {....bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);} 復制代碼3.如果已經(jīng)創(chuàng)建,拋出異常
else {if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);} 復制代碼4.在父BeanFactory查找
BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}} 復制代碼5.創(chuàng)建標記,(用于清除)
if (!typeCheckOnly) {markBeanAsCreated(beanName);} 復制代碼6.尋找bean定義信息,并針對bean定義進行驗證
try {final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args); 復制代碼7.處理依賴信息,這里會針對xml定義中的depends-on進行處理
String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dependsOnBean : dependsOn) {if (isDependent(beanName, dependsOnBean)) {....registerDependentBean(dependsOnBean, beanName);getBean(dependsOnBean);}} 復制代碼具體通過這個私有方法來解決依賴的 假設A依賴于B,那么在創(chuàng)建A之前,必須保證B先被創(chuàng)建。 在創(chuàng)建了B之后,這里會進行依賴信息存儲。后面在遞歸調(diào)用一下,不過依賴關系反過來。 dependentBeanMap放 A->[B,C,D] (A所依賴的B,C,D)
private boolean isDependent(String beanName, String dependentBeanName, Set<String> alreadySeen) {if (alreadySeen != null && alreadySeen.contains(beanName)) {return false;}String canonicalName = canonicalName(beanName);Set<String> dependentBeans = this.dependentBeanMap.get(canonicalName);if (dependentBeans == null) {return false;}if (dependentBeans.contains(dependentBeanName)) {return true;}for (String transitiveDependency : dependentBeans) {if (alreadySeen == null) {alreadySeen = new HashSet<String>();}alreadySeen.add(beanName);if (isDependent(transitiveDependency, dependentBeanName, alreadySeen)) {return true;}}return false;} 復制代碼單例模式就調(diào)用getSingleton(String beanName, ObjectFactory<?> singletonFactory)
// 單例if (mbd.isSingleton()) {....bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);} 復制代碼 public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {....synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);....beforeSingletonCreation(beanName);....singletonObject = singletonFactory.getObject();....addSingleton(beanName, singletonObject);}return (singletonObject != NULL_OBJECT ? singletonObject : null);}} 復制代碼原型模式
else if (mbd.isPrototype()) {Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);} 復制代碼其他模式,比如scope=request
else {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);....try {Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {public Object getObject() throws BeansException {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}....}}....} 復制代碼8.無論哪種模式都會進入AbstractAutowireCapableBeanFactory的createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
....RootBeanDefinition mbdToUse = mbd;// 解析beanDefinition,以確保bean定義中的class可以被正確解析Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}....try {// 如果實現(xiàn)了InstantiationAwareBeanPostProcessor就先postProcessBeforeInstantiation(Class<?> beanClass, String beanName)->postProcessAfterInitialization(Object bean, String beanName)Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}....Object beanInstance = doCreateBean(beanName, mbdToUse, args);....}return beanInstance; 復制代碼9.Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
....if (exposedObject != null) {exposedObject = initializeBean(beanName, exposedObject, mbd);}....復制代碼10.Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd)
if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {public Object run() {//setBeanName#BeanNameAware//->setBeanClassLoader#BeanClassLoaderAware//->setBeanFactory#BeanFactoryAwareinvokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {//->postProcessBeforeInitialization#BeanPostProcessorwrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//->afterPropertiesSet#InitializingBeaninvokeInitMethods(beanName, wrappedBean, mbd);}....if (mbd == null || !mbd.isSynthetic()) {//->postProcessAfterInitialization#BeanPostProcessorwrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean; 復制代碼 private void invokeAwareMethods(final String beanName, final Object bean) {if (bean instanceof Aware) {if (bean instanceof BeanNameAware) {((BeanNameAware) bean).setBeanName(beanName);}if (bean instanceof BeanClassLoaderAware) {((BeanClassLoaderAware) bean).setBeanClassLoader(getBeanClassLoader());}if (bean instanceof BeanFactoryAware) {((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);}}} 復制代碼 protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)throws Throwable {boolean isInitializingBean = (bean instanceof InitializingBean);if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {....if (System.getSecurityManager() != null) {try {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {public Object run() throws Exception {((InitializingBean) bean).afterPropertiesSet();return null;}}, getAccessControlContext());}catch (PrivilegedActionException pae) {throw pae.getException();}}else {((InitializingBean) bean).afterPropertiesSet();}}if (mbd != null) {String initMethodName = mbd.getInitMethodName();if (initMethodName != null && !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&!mbd.isExternallyManagedInitMethod(initMethodName)) {invokeCustomInitMethod(beanName, bean, mbd);}}} 復制代碼postProcessBeforeInstantiation(Class<?> beanClass, String beanName)#InstantiationAwareBeanPostProcessor ->postProcessAfterInitialization(Object bean, String beanName)#InstantiationAwareBeanPostProcessor ->setBeanName#BeanNameAware ->setBeanClassLoader#BeanClassLoaderAware ->setBeanFactory#BeanFactoryAware ->postProcessBeforeInitialization#BeanPostProcessor ->afterPropertiesSet#InitializingBean ->postProcessAfterInitialization#BeanPostProcessor
public class InitAndDestroySeqBean implements InitializingBean,DisposableBean,BeanPostProcessor,InstantiationAwareBeanPostProcessor {public InitAndDestroySeqBean() {System.out.println("構造方法");}public void postConstruct(){System.out.println("@PostConstruct");} public void afterPropertiesSet() throws Exception {System.out.println("afterPropertiesSet()#InitializingBean");}public void initMethod(){System.out.println("init-method");}public void preDestroy(){System.out.println("@PreDestroy");} public void destroy() throws Exception {System.out.println("destroy()#DisposableBean");}public void destroyMethod(){System.out.println("destroy-method");} public Object postProcessBeforeInitialization(Object bean, String beanName)throws BeansException {System.out.println("postProcessBeforeInitialization(Object bean, String beanName)#BeanPostProcessor");return bean;} public Object postProcessAfterInitialization(Object bean, String beanName)throws BeansException {System.out.println("postProcessAfterInitialization(Object bean, String beanName)#BeanPostProcessor");return bean;} public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)throws BeansException {System.out.println("postProcessBeforeInstantiation(Class<?> beanClass, String beanName)#InstantiationAwareBeanPostProcessor");return null;} public boolean postProcessAfterInstantiation(Object bean, String beanName)throws BeansException {System.out.println("postProcessAfterInstantiation(Object bean, String beanName)#InstantiationAwareBeanPostProcessor");return false;} public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds,Object bean, String beanName) throws BeansException {System.out.println("postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds,\n"+ " Object bean, String beanName)#InstantiationAwareBeanPostProcessor");return null;} }復制代碼20170308:11:34:52.866 [main] INFO Using TestExecutionListeners: [org.springframework.test.context.web.ServletTestExecutionListener@49c43f4e, org.springframework.test.context.support.DirtiesContextBeforeModesTestExecutionListener@290dbf45, org.springframework.test.context.support.DependencyInjectionTestExecutionListener@12028586, org.springframework.test.context.support.DirtiesContextTestExecutionListener@17776a8, org.springframework.test.context.transaction.TransactionalTestExecutionListener@69a10787, org.springframework.test.context.jdbc.SqlScriptsTestExecutionListener@2d127a61]20170308:11:34:52.972 [main] INFO Loading XML bean definitions from URL [file:/Users/dsc/IdeaProjects/firDemo/firdemo/web/target/classes/init.xml] 20170308:11:34:53.105 [main] INFO Refreshing org.springframework.context.support.GenericApplicationContext@2b4a2ec7: startup date [Wed Mar 08 11:34:53 CST 2017]; root of context hierarchy 構造方法 @PostConstruct afterPropertiesSet()#InitializingBean init-method postProcessBeforeInstantiation(Class<?> beanClass, String beanName)#InstantiationAwareBeanPostProcessor postProcessAfterInstantiation(Object bean, String beanName)#InstantiationAwareBeanPostProcessor postProcessBeforeInitialization(Object bean, String beanName)#BeanPostProcessor postProcessAfterInitialization(Object bean, String beanName)#BeanPostProcessor postProcessBeforeInstantiation(Class<?> beanClass, String beanName)#InstantiationAwareBeanPostProcessor postProcessAfterInstantiation(Object bean, String beanName)#InstantiationAwareBeanPostProcessor postProcessBeforeInitialization(Object bean, String beanName)#BeanPostProcessor postProcessAfterInitialization(Object bean, String beanName)#BeanPostProcessor postProcessAfterInstantiation(Object bean, String beanName)#InstantiationAwareBeanPostProcessor postProcessBeforeInitialization(Object bean, String beanName)#BeanPostProcessor postProcessAfterInitialization(Object bean, String beanName)#BeanPostProcessor 20170308:11:34:53.286 [Thread-0] INFO Closing org.springframework.context.support.GenericApplicationContext@2b4a2ec7: startup date [Wed Mar 08 11:34:53 CST 2017]; root of context hierarchy @PreDestroy destroy()#DisposableBean destroy-method
總結
以上是生活随笔為你收集整理的从源码了解spring bean实例化过程的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java并发工具类(闭锁CountDow
- 下一篇: 【天池直播--预告】美女程序猿带你用大数