Spring Web项目中 ApplicationContext 的获取和创建Bean的过程1
ApplicationContext ctx = (ApplicationContext) ContextLoader.getCurrentWebApplicationContext();TransactionTemplate transactiontemplate = (TransactionTemplate)ctx.getBean("mes_default_transactionTemplate" ); transactiontemplate.execute( new TransactionCallback() { @Override public Object doInTransaction(TransactionStatus status) { dataAdapter.delete( "delete from mes_do_used where frompid = #pid#",para); dataAdapter.delete( "delete from mes_daily_turn where frompid = #pid#",para); return null ; } });?这段代码是在web项目中获取ApplicationContext对象,然后实例化事务模板 ,用事务管理来删除数据的代码??Web项目里,项目启动的时候ApplicationContext对象就已经建立了,在Web.xml里配置ContexLoaderListener后,启动的时候会执行Listener生成AapplicationContext对象,存储到ServletContext对象中?所以在业务代码中,我们需要想办法获取到ApplicationContext对象,然后用这个对象实现工厂模式,返回一个TransactionTemplate实例。?我们所需要用到的类 都在org.springframework.web.context这个包下面??我们访问 抽象类?ContextLoader ?这个类是org.springframework.web.context包里面的抽象类,他有很多静态方法,可以直接用。其中:
public static WebApplicationContext getCurrentWebApplicationContext() { return (WebApplicationContext) currentContextPerThread .get(Thread.currentThread ().getContextClassLoader()); }?这个方法 就可以用来获得WebApplicationContext?对象?WebApplicationContext?对象是继承自ApplicationContext的,可以直接做转换????然后 ? ? ?ctx.getBean("mes_default_transactionTemplate"?);? ? 这样就从ApplicationContext.xml中的bean配置中 找到了对应的类路径 实例化这个对象? ? ?getBean 是Spring 的工厂模式 是BeanFactroy接口里的方法 ?这个接口在包? ? ?org.springframework.beans.factory里面? ?我们看看源码:getBean?(String name) 方法在源码里层层往下找 最后在这里找到org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(String?name,?Class?requiredType,?Object[] args, boolean typeCheckOnly)?.AbstractBeanFactory这个类里面有实现 叫做doGetBean方法这个方法里有这一行 ??bean = getObjectForBeanInstance(sharedInstance, name, beanName,?null);所以还得接着找getObjectForBeanInstanc方法的实现接着看getObjectForBeanInstanc方法 里面是object = getCachedObjectForFactoryBean(beanName);这行?继续找getCachedObjectForFactoryBean最后找到了getObjectFromFactoryBean();?贴出源代码:org.springframework.beans.factory.support.FactoryBeanRegistrySupport.getObjectFromFactoryBean(FactoryBean?factory,?String?beanName, boolean shouldPostProcess)
protected Object getObjectFromFactoryBean(FactoryBean factory, String beanName, boolean shouldPostProcess) { if (factory.isSingleton() && containsSingleton(beanName)) { synchronized (getSingletonMutex()) { Object object = this.factoryBeanObjectCache .get(beanName); if (object == null) { object = doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); this.factoryBeanObjectCache .put(beanName, (object != null ? object : NULL_OBJECT)); } return (object != NULL_OBJECT ? object : null); } } else { return doGetObjectFromFactoryBean(factory, beanName, shouldPostProcess); } }??factoryBeanObjectCache?是Spring 存放Bean实例对象的集合,Spring建好的对象就都放在这里了。代码里首先从factoryBeanObjectCache里面去取,去得到就返回,取不到就doGetObjectFromFactoryBean();方法去建立bean对象然后放到factoryBeanObjectCache里面去 再返回新建的bean对象?但是这里doGetObjectFromFactoryBean()还是没有到最终实现,所以要继续往下 到这个方法org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBean?factory,?String?beanName, boolean shouldPostProcess)? ?
private Object doGetObjectFromFactoryBean( final FactoryBean factory, final String beanName, final boolean shouldPostProcess) throws BeanCreationException { AccessControlContext acc = AccessController. getContext(); return AccessController.doPrivileged( new PrivilegedAction() { public Object run() { Object object; try { object = factory.getObject(); } catch (FactoryBeanNotInitializedException ex) { throw new BeanCurrentlyInCreationException(beanName, ex.toString()); } catch (Throwable ex) { throw new BeanCreationException(beanName, "FactoryBean threw exception on object creation" , ex); } // Do not accept a null value for a FactoryBean that's not fully // initialized yet: Many FactoryBeans just return null then. if (object == null && isSingletonCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException( beanName, "FactoryBean which is currently in creation returned null from getObject"); } if (object != null && shouldPostProcess) { try { object = postProcessObjectFromFactoryBean(object, beanName); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Post-processing of the FactoryBean's object failed", ex); } } return object; } }, acc); }??可以看到 主要是?object = factory.getObject(); ?其余的都是获取不到Object时报异常用的代码?进一步 看factory.getObject(); ?org.springframework.beans.factory.config.AbstractFactoryBean.getObject()
public final Object getObject() throws Exception { if (isSingleton()) { return (this .initialized ? this. singletonInstance : getEarlySingletonInstance()); } else { return createInstance(); } }??也是先看是不是单例模式,是的话就判断是不是已经实例化过,如果已经实例化过,就把早先实例化好的对象返回出来如果不是单例模式 就直接创建新实例?createInstance();??createInstance();再往下本次就不继续看了??????? ??