Seam


以Key-组件Class Value-组件@Name内的名称,名称缓存
同时缓存EJB部署描述符及EJB类加载器
//$Id: Seam.java 10262 2009-04-01 07:03:21Z dan.j.allen $
package org.jboss.seam;

import static org.jboss.seam.ComponentType.ENTITY_BEAN;
import static org.jboss.seam.ComponentType.JAVA_BEAN;
import static org.jboss.seam.ComponentType.MESSAGE_DRIVEN_BEAN;
import static org.jboss.seam.ComponentType.STATEFUL_SESSION_BEAN;
import static org.jboss.seam.ComponentType.STATELESS_SESSION_BEAN;
import static org.jboss.seam.util.EJB.MESSAGE_DRIVEN;
import static org.jboss.seam.util.EJB.STATEFUL;
import static org.jboss.seam.util.EJB.STATELESS;
import static org.jboss.seam.util.EJB.name;

import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.Entity;

import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Role;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.annotations.intercept.BypassInterceptors;
import org.jboss.seam.contexts.Contexts;
import org.jboss.seam.contexts.Lifecycle;
import org.jboss.seam.init.EjbDescriptor;
import org.jboss.seam.init.DeploymentDescriptor;
import org.jboss.seam.util.Strings;
import org.jboss.seam.web.Session;

/**
* Convenience methods for accessing annotated information
* about Seam component classes.
* 利用全局缓存保存Seam组件,EJB部署描述符,类加载器
* Model保存bean class或者是说保存Seam组件保存的Class,而Component保存在ApplicationContext中
* Seam保存Component的Class
*
* @author Gavin King
*/
public class Seam
{
private static final Map<Class, String> COMPONENT_NAME_CACHE = new ConcurrentHashMap<Class, String>();
private static final Map<Class, EjbDescriptor> EJB_DESCRIPTOR_CACHE = new ConcurrentHashMap<Class, EjbDescriptor>();
private static final Set<ClassLoader> CLASSLOADERS_LOADED = new HashSet<ClassLoader>();

// application-scoped property in which the Seam version is stored
public static final String VERSION = "org.jboss.seam.version";
/**
* 获取EJB描述符,如果缓存中没有,则利用ClassLoader进行加载,同时缓存ClassLoader
*/
public static EjbDescriptor getEjbDescriptor(Class clazz)
{
EjbDescriptor info = EJB_DESCRIPTOR_CACHE.get(clazz);
if (info != null)
{
return info;
}
else if (!CLASSLOADERS_LOADED.contains(clazz.getClassLoader()))
{
cacheEjbDescriptors(clazz);
return EJB_DESCRIPTOR_CACHE.get(clazz);
}

return null;
}
/**
* 对全局变量进行操作,进行了同步
*/
private synchronized static void cacheEjbDescriptors(Class clazz)
{
if (!CLASSLOADERS_LOADED.contains(clazz.getClassLoader()))
{
Map<Class, EjbDescriptor> ejbDescriptors = new DeploymentDescriptor(clazz).getEjbDescriptors();
EJB_DESCRIPTOR_CACHE.putAll(ejbDescriptors);
CLASSLOADERS_LOADED.add(clazz.getClassLoader());
}
}

/**
* Get the default scope
* @see Scope
*/
public static ScopeType getComponentScope(Class<?> clazz)
{
return clazz.isAnnotationPresent(Scope.class) ?
clazz.getAnnotation(Scope.class).value() :
getComponentType(clazz).getDefaultScope();//根据组件类型 获取默认的Scope
}

/**
* Get the scope for a role
* @see Scope
*/
public static ScopeType getComponentRoleScope(Class clazz, Role role)
{
return role.scope()==ScopeType.UNSPECIFIED ?
getComponentType(clazz).getDefaultScope() :
role.scope();
}

/**
* Get the component type
*/
public static ComponentType getComponentType(Class<?> clazz)
{
if ( clazz.isAnnotationPresent(STATEFUL) ) //是否标记Seam物状态
{
return STATEFUL_SESSION_BEAN;
}
else if ( clazz.isAnnotationPresent(STATELESS) )
{
return STATELESS_SESSION_BEAN;
}
else if ( clazz.isAnnotationPresent(MESSAGE_DRIVEN) )
{
return MESSAGE_DRIVEN_BEAN;
}
else if ( clazz.isAnnotationPresent(Entity.class) )
{
return ENTITY_BEAN;
}
else
{
EjbDescriptor ejbDescriptor = getEjbDescriptor(clazz);//根据Ejb描述符获取Bean的类型
if (ejbDescriptor == null)
{
return JAVA_BEAN; //默认为Java bean
}
else
{
return ejbDescriptor.getBeanType();
}
}
}

/**
* Get the component name
* @see Name
*/
public static String getComponentName(Class<?> clazz)
{
String result = COMPONENT_NAME_CACHE.get(clazz);
if (result==null)
{
result = searchComponentName(clazz);
if (result!=null)
{
COMPONENT_NAME_CACHE.put(clazz, result);
}
}
return result;
}
/**
* 获取@Name的Value,如果没有则找寻父类,一直到Object.class
*/
public static String searchComponentName(Class<?> clazz)
{
while ( clazz!=null && !Object.class.equals(clazz) )
{
Name name = clazz.getAnnotation(Name.class);
if ( name!=null ) return name.value();
clazz = clazz.getSuperclass();
}
return null;
}

/**
* Get the bean class from a container-generated proxy
* class
* 1.是否有Entity标记 >return
* < if EJB描述符具有 > if 是EntityBean >return clazz
* <return null
* < clazz = clazz.super..
* 最后< return
*/
public static Class getEntityClass(Class clazz)
{
while (clazz != null && !Object.class.equals(clazz))
{
if (clazz.isAnnotationPresent(Entity.class))
{
return clazz;
}
else
{
EjbDescriptor ejbDescriptor = Seam.getEjbDescriptor(clazz);
if (ejbDescriptor != null)
{
return ejbDescriptor.getBeanType() == ComponentType.ENTITY_BEAN ? clazz : null;
}
else
{
clazz = clazz.getSuperclass();
}
}
}
return null;
}

/**
* Is the class a container-generated proxy class for an
* entity bean?
*/
public static boolean isEntityClass(Class<?> clazz)
{
return getEntityClass(clazz)!=null;
}
/**
* 获取EJB组件名称,1 元数据 2 xml
*/
public static String getEjbName(Class<?> clazz)
{
switch ( getComponentType(clazz) )
{
case ENTITY_BEAN:
case JAVA_BEAN:
return null;
case STATEFUL_SESSION_BEAN:
return clazz.isAnnotationPresent(STATEFUL) ?
getStatefulEjbName(clazz) : getEjbNameFromDescriptor(clazz);
case STATELESS_SESSION_BEAN:
return clazz.isAnnotationPresent(STATELESS) ?
getStatelessEjbName(clazz) : getEjbNameFromDescriptor(clazz);
case MESSAGE_DRIVEN_BEAN:
return clazz.isAnnotationPresent(MESSAGE_DRIVEN) ?
getMessageDrivenEjbName(clazz) : getEjbNameFromDescriptor(clazz);
default:
throw new IllegalArgumentException();
}
}

private static String getMessageDrivenEjbName(Class<?> clazz)
{
String mdName = name( clazz.getAnnotation(MESSAGE_DRIVEN) );
return mdName.equals("") ? unqualifyClassName(clazz) : mdName;
}

private static String getStatelessEjbName(Class<?> clazz)
{
String statelessName = name( clazz.getAnnotation(STATELESS) );
return statelessName.equals("") ? unqualifyClassName(clazz) : statelessName;
}

private static String getStatefulEjbName(Class<?> clazz)
{
String statefulName = name( clazz.getAnnotation(STATEFUL) );
return statefulName.equals("") ? unqualifyClassName(clazz) : statefulName;
}

private static String getEjbNameFromDescriptor(Class<?> clazz)
{
EjbDescriptor ejbDescriptor = getEjbDescriptor(clazz);
return ejbDescriptor==null ? null : ejbDescriptor.getEjbName();
}

private static String unqualifyClassName(Class<?> clazz)
{
return Strings.unqualify( Strings.unqualify( clazz.getName() ), '$' );
}

public static boolean isInterceptionEnabled(Class<?> clazz)
{
ComponentType componentType = getComponentType(clazz);
if ( componentType==ENTITY_BEAN )
{
return false; //entity bean 无拦截
}
else if ( getComponentType(clazz)==MESSAGE_DRIVEN_BEAN )
{
return true;
}
else if ( clazz.isAnnotationPresent(BypassInterceptors.class) )
{
return false;
}
else
{
return true;
}
}

/**
* Mark the session for invalidation at the end of the
* request cycle
*
* @deprecated use Session.instance().invalidate()
*/
public static void invalidateSession()
{
Session.instance().invalidate();
}

/**
* Is the session marked for invalidation?
*
* @deprecated use Session.instance().isInvalidated()
*/
public static boolean isSessionInvalid()
{
return Session.instance().isInvalid();
}

/**
* Get the Seam component, even if no application context
* is associated with the current thread.
*/
public static Component componentForName(String name)
{
if ( Contexts.isApplicationContextActive() )
{
return Component.forName(name);
}
else
{
Lifecycle.setupApplication();
try
{
return Component.forName(name);
}
finally
{
Lifecycle.cleanupApplication();
}
}
}

public static String getVersion()
{
Package pkg = Seam.class.getPackage();
return pkg != null ? pkg.getImplementationVersion() : null;
}

public static void clearComponentNameCache()
{
COMPONENT_NAME_CACHE.clear();
EJB_DESCRIPTOR_CACHE.clear();
}

}


### SEAM Framework 的核心概念及其与 Java EE 和 JSF 的集成 SEAM 是一种用于简化企业级应用开发的框架,其设计目标是通过减少样板代码和复杂配置来提升开发者效率。以下是关于 SEAM 及其与 Java EE 和 JSF 集成的关键点: #### 1. **SEAM 对 JSF 的增强** SEAM 将 JSF 定位为其首选的表示层框架,并对其进行了显著改进。具体来说,SEAM 提供了一种更灵活的方式来管理组件生命周期以及事件处理机制[^1]。这种增强使得 JSF 更加适合构建复杂的 Web 应用程序。 #### 2. **JSF 在 Java EE 中的角色** 作为 Java EE 平台的一部分,JSF 被定义为官方的基于组件的视图技术。它不仅提供了一系列预定义的 UI 组件,还支持事件驱动编程模型以及第三方组件的扩展能力[^2]。这使 JSF 成为了一个功能强大且高度可定制化的前端解决方案。 #### 3. **Apache MyFaces 支持下的 JSF 开发** 对于希望快速启动项目的开发者而言,可以利用 `org.apache.myfaces.buildtools:myfaces-archetype-jsfcomponents` 来创建标准的 Apache MyFaces JSF 组件项目结构[^3]。这种方式能够帮助团队更快地进入实际编码阶段而无需花费过多时间在初始设置上。 #### 4. **整体架构视角下 SEAM 的优势** 尽管 SEAM 同样兼容其他展示层框架(如 JSP 或 Facelets),但在书中主要讨论的是如何结合使用 JSF 实现更加现代化、交互性强的应用界面。因此,在考虑采用何种工具链时,如果已经决定选用 JSF,则搭配 SEAM 往往能带来额外的好处——比如更好的状态管理和事务控制等功能特性。 ```java // 示例:简单的 JSF 页面绑定逻辑 @Named @SessionScoped public class UserBean implements Serializable { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } } ``` 上述代码片段展示了如何在一个典型的 JSF Bean 类中实现基本属性封装操作。当此 bean 注入到页面后即可直接访问其中的数据字段并完成相应业务流程调用。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值