IT民工窝棚qbq.blog.chinaunix.net
qbq
全部博文(708)
国产(1)
欧美(1)
SEO(1)
CSS3(5)
TestNG(4)
HTML5(2)
iBatis(3)
URLRewrite(1)
WebService(1)
WebServer(12)
PHP(8)
OGNL(1)
AS2(2)
Multimedia(0)
Flex AS3(29)
面试(9)
Commet(1)
Ivy(2)
Bat(8)
Maven(18)
CSS(7)
Ext(9)
Spring问题集(4)
Word(1)
JFreeChart(2)
Groovy on Grails(14)
Python(1)
Portlet(3)
amCharts(4)
CSharp.NET(3)
Tools(1)
S2Dao(8)
HSQL(9)
taglib(28)
Source Safe(3)
JSTL(6)
EL(2)
Seasar-SAStruts(3)
Prototype(0)
JQuery(3)
DWR(7)
AJAX(14)
Guice(13)
Digit(2)
Notebook(4)
Log4J(8)
Servlet(2)
JSP(4)
Eclipse(12)
VB.NET(3)
DotNet(3)
JavaScript(63)
Thinking In Soft(10)
Framework(11)
English(0)
Struts2(14)
Struts(38)
Hibernate(10)
Spring(30)
HTML(14)
Web(5)
MYSQL(9)
SQLSERVER(1)
ORACLE(2)
SQL(3)
数据库(0)
DATABASE(0)
Windows(8)
JAVA(67)
Software(1)
Hardware(3)
OpenSource(2)
Microsoft(0)
Excel(4)
DIY(5)
Linux(4)
分类: Java
2008-03-31 14:56:30
我们知道,在Spring2.0中,除了singleton及prototype两种类型的Bean以外。默认情况下还增加了request、session及global session三种类型的Bean,增加的三种类型的Bean主要应用于Web应用程序中。本文不打算分析三种类型的Bean的用法,只是简单分析框架的实现原理。 Spring2.0中新增了一个用来表示Bean范围的Scope接口 public interface Scope { Object get(String name, ObjectFactory objectFactory);//根据名称及创建工厂得到一个Bean实例 Object remove(String name);//删除一个指定名称的Bean } 在容器ConfigurableBeanFactory接口中定义了Bean工厂有关Scope注册的相关方法,使得可往Bean工厂中加入新类型的Bean。 public interface ConfigurableBeanFactory extends HierarchicalBeanFactory, void registerScope(String scopeName, Scope scope);//往Bean工厂中添加一个新的范围(默认只有两种范围:singleton及prototype) void destroyScopedBean(String beanName);//销毁B ean工厂中范围Bean } 在AbstractFactoryBean的getBean方法中实现了对特定Scope Bean支持,核心代码摘要: String scopeName = mergedBeanDefinition.getScope();//取得当前Bean的范围,也即在定义中的scope=”request”的部分。 Scope scope = (Scope) this.scopes.get(scopeName);//得到Bean工厂中的范围处理器 if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + scopeName + "'"); } try {//使用scope.get(beanName,ObjectFactory)从指定的范围中得到或创建Bean实例 Object scopedInstance = scope.get(beanName, new ObjectFactory() { public Object getObject() throws BeansException { beforePrototypeCreation(beanName);//前拦截 try { return createBean(beanName, mergedBeanDefinition, args);//调用子类的createBean实现真正的Bean创建工作 } finally { afterPrototypeCreation(beanName);//后拦截 } } }); bean = getObjectForBeanInstance(scopedInstance, name, mergedBeanDefinition);//返回正确类型的Bean实例 } catch (IllegalStateException ex) { throw new BeanCreationException(beanName, "Scope '" + scopeName + "' is not active", ex); } 默认情况下,低层的Bean工厂中只支持singleton及prototype两种类型的Bean.当把scope设置成request及session时将会出现不能正确识别Scope的错误。这是因为普通的Bean工厂都没有注册新的Scope.只有在WebApplicationContext中注册才注册了新类型的Bean.下面看实现注册Scope的代码: 在WebApplicationContext中定义常量 public interface WebApplicationContext extends ApplicationContext { String SCOPE_REQUEST = "request"; String SCOPE_SESSION = "session"; String SCOPE_GLOBAL_SESSION = "globalSession";} 然后在所有类型的Web应用上下文的实现中,都在Bean工厂的拦载过程中通过postProcessBeanFactory方法来注册新类型Scope,如GenericWebApplicationContext、StaticWebApplicationContext、AbstractRefreshableWebApplicationContext等WebApplication应用上下文实现中。 protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { beanFactory.registerScope(SCOPE_REQUEST, new RequestScope());//注册request类型的Bean beanFactory.registerScope(SCOPE_SESSION, new SessionScope(false));//注册session类型的Bean beanFactory.registerScope(SCOPE_GLOBAL_SESSION, new SessionScope(true));//注册glogalsession 的Bean} 结合上面的代码,现在应该明白为什么只有在Web应用上下文中才能使用新增加三种类型的Bean了吧。当然,由于有了Scope,我们也可以非常轻松的实现我们自己的Scope,增加新用户自定义类型的Bean,然后设计出一个适合我们自己的Bean工厂。
上一篇:对于Struts和Spring两种MVC框架的比较
下一篇:详细讲解在Spring中进行集成测试
登录 注册