?
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();再往下本次就不继续看了
?
?
?
?
?
?
? ??