jboss seam 中的 Component

本文讲述Seam组件的初始化和实例化过程。

[b][size=medium]初始化seam组件[/size][/b]

SeamListener.contextInitialized(...)

new Initialization(servletContext).create().init();

Initialization.create()

StandardDeploymentStrategy.scan();
通过UrlScanner 扫描包含 seam.properties, META-INF/seam.properties 或 META-INF/components.xml的文件夹和jar文件。

ComponentDeploymentHandler.handle(...)
针对每一个扫描到的ClassFile, 如满足以下两个条件,则标记为seam 组件:
1. 有@Name标注或有一个同名的.component.xml文件存在;
2. 无@Install标注或有@Install 标注且 value = false;

initComponentsFromXmlDocument("/WEB-INF/components.xml")
安装WEB-INF/components.xml中定义的组件;

initComponentsFromXmlDocuments();
安装所有META-INF/components.xml中定义的组件;

Initialization.init()

scanForComponents()
安装StandardDeploymentStrategy扫描到的seam组件;

addComponent( new ComponentDescriptor(Init.class), ...)
安装Init组件;

addSpecialComponents(init)
安装PojoCache组件;

installComponents(init)
安装依赖组件?

Initialization.addComponent(descriptor, context)

component = new Component(...);
context.set(componentName, component);
所有的Seam组件都安装到了ApplicationContext中了.下面我们来看如何获得组件。


[b][size=medium]Seam组件的实例化[/size][/b]

即然组件交由seam来管理,那么就不能使用new来实例化了,必须通过Component对象来完成。

Component.newInstance()

instance = instantiate();
if (getScope()!=STATELESS) {
//存入Context,
getScope().getContext().set(name, instance);
......
}


Component.instantiate()

switch(type) {
case JAVA_BEAN:
return instantiateJavaBean();
case ENTITY_BEAN:
return instantiateEntityBean();
case STATELESS_SESSION_BEAN:
case STATEFUL_SESSION_BEAN:
return instantiateSessionBean();
......
}

根据组件的类型执行不同的实例化操作。


[b]Pojo组件的实例化[/b]

Component.instantiateJavaBean()

Object bean = getBeanClass().newInstance();
if (!interceptionEnabled) {
initialize(bean);
callPostConstructMethod(bean);
}
else {
JavaBeanInterceptor interceptor = new JavaBeanInterceptor(bean, this);
bean = wrap(bean, interceptor); // 创建Proxy对象
interceptor.postConstruct(); // 由PostConstruct调用initialize(bean)
}


判断此组件是否允许被Interceptor,这由BypassInterceptors描述决定,
如允许被Interceptor,则创建Proxy对象并加入interceptor对象,
有关Interceptor的内容我们将在下一篇文章中详述。

[b]Entity组件的实例化[/b]

Component.instantiateEntityBean()
Object bean = getBeanClass().newInstance();
initialize(bean);

[b]Session组件的实例化[/b]

Component.instantiateSessionBean()
Object bean = Naming.getInitialContext().lookup(jndiName);
return wrap(bean, new ClientSideInterceptor(bean, this));

Session组件由JNDI进行管理,获得Session组件后,创建一个Proxy对象对它进行封装,
ClientSideInterceptor为客户端的拦截器。


[b][size=medium]Seam组件的调用[/size][/b]

通过Component类,可以非常容易的获得seam组件,查找的顺序如下:

1. Seam从给定的Scope Context中查找,如未指定Scope,则查找所有Context;
2. 如未找到组件,则查找是否有工厂方法;
3. 如未找到工厂方法,则使用newInstance方法实例化组件并存入相应Scope的Context中;
4. unwrap组件;

Component.getInstance(name)
// 查找所有Context
Object result = Contexts.lookupInStatefulContexts(name);
result = getInstance(name, create, result);
return result;

Component.getInstance(name, scope)
// 查找scope的Context
Object result = scope==STATELESS ? null : scope.getContext().get(name);
result = getInstance(name, create, result);
return result;

Component.getInstance(name, create, result)

if (result == null && create) {
// 通过工厂模式创建.
result = getInstanceFromFactory(name);
if (result == null) {
if (component== null) {
}
else if (component.getScope().isContextActive()) {
// 检查Context是否为激活状态
result = component.newInstance();
}
}

if (result != null) {
if (component != null) {
if (!component.isInstance(result)) {
// 检查result为有效的bean实例
if (component.hasUnwrapMethod())
return result;
}
result = component.unwrap(result);
}
}
return result;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值