Apche deltaSpike笔记: deltaSpike Core Module[必须]

 概述
核心模块提供了基本的定义deltaspike API和工具类。因此,使用deltaspike,则该模块必须包含。

deltaspike配置机制

关于ds的配置,单有较多并且非常安全[非硬编码],方便的方法进行配置.
简单的使用就是使用其提供的CDI 注解:@ConfigProperty
也可以通过ConfigResolver注入来获取对应的值.

1.ConfigResolver

getPropertyValue()方法:
String dbUserName = ConfigResolver.getPropertyValue("databaseconfig.username");
通过查找,返回一个字符串或者null.
ConfigResolver.getAllPropertyValues(String key) 与上面方法类似,但返回的是一个List,也可能是空的List.

getProjectStageAwarePropertyValue()方法:
ConfigResolver.getProjectStageAwarePropertyValue(String key, String property)首先查找给定属性的设置值,使用这个值来确定最终的查找路径。
这些查询以deltaspike projectstage机制查询。[deltaspike projectstage: http://deltaspike.apache.org/documentation/projectstage.html]
示例:
String dbUserName = ConfigResolver.getPropertyAwarePropertyValue("databaseconfig.username", "dbvendor");
开始查询,我们首先要解决的是property的值.
propertyValue = property + '.' + projectStage, e.g. "dbvendor.Production"
如果没有查询到: propertyValue = property, e.g. "dbvendor"
假设我们发现dbvendor值为:mysql。在这种情况下,使用以下查找,直到发现了真正的值:
  • key + '.' + property + projectstage, e.g. "databaseconfig.username.mysql.Production" 
  • key + '.' + property, e.g. "databaseconfig.username.mysql" 
  • key + '.' + projectstage, e.g. "databaseconfig.username.Production" 
  • key, e.g. "databaseconfig.username" 

这块比较复杂,我也没用过,请参考
 http://deltaspike.apache.org/documentation/configuration.html
 http://deltaspike.apache.org/documentation/projectstage.html

2.ConfigSource

默认的配置属性文件是位于 :/META-INF/apache-deltaspike.properties
DS也提供了自定义配置文件的方法.通过对PropertyFileConfig的实现来做.
public class MyCustomPropertyFileConfig implements PropertyFileConfig 
{ 
    @Override 
    public String getPropertyFileName() 
    { 
        return "myconfig.properties"; 
    } 
}
看文档中描述应该还有更复杂的方式.不做研究,反正也用不到.

3.@ConfigProperty 常用

相对简单的一种配置属性读取方式

DS整个的先后顺序为:
  1. System properties (deltaspike_ordinal = 400)
  2. Environment properties (deltaspike_ordinal = 300)
  3. JNDI values (deltaspike_ordinal = 200, the base name is "java:comp/env/deltaspike/")
  4. Properties file values (apache-deltaspike.properties) (deltaspike_ordinal = 100, default filename is "META-INF/apache-deltaspike.properties")
  5. 注入点的默认值.
如下代码:
@ApplicationScoped 
public class SomeRandomService 
{ 
    @Inject 
    @ConfigProperty(name = "endpoint.poll.interval", defaultValue = "11") 
    private Integer pollInterval; 

    @Inject 
    @ConfigProperty(name = "endpoint.poll.servername", defaultValue = "www.baidu.com") 
    private String pollUrl; 
    ...  } 

在实际的使用为,首先配置jboss配置文件中的系统参数.然后配置META-INF/apache-deltaspike.properties的参数.最后配置注入点的defaultValue.避免空值. 

其将按顺序进行读取.
JBOSS下配置为: <system-properties> 节点下进行配置,也是和properties文件一样是key,value的模式.
如:
<system-properties> 
        <property name="endpoint.poll.interval" value="15"/> 
</system-properties> 

BeanProvider

解决一个简单的上下文实例:
MyBean myBean = BeanProvider.getContextualReference(MyBean.class, false); 

如果你寻找给定的接口和一个实现,第二个参数传递True 
解决一个可选的上下文实例: 

MyServiceInterface optionalService = BeanProvider.getContextualReference(MyServiceInterface.class, true); 

也可以通过cdi 注解的方式获取对应的实例: 
Literal Implementation for '@MyQualifier' 

import javax.enterprise.util.AnnotationLiteral; 
//... 
public class MyQualifierLiteral extends AnnotationLiteral<MyQualifier> implements MyQualifier 
{ 
} 

更多的用法:

//以下示例将返回一个与”@myqualifier相关的上下文实例。 
MyBean myBean = BeanProvider.getContextualReference(MyBean.class, false, new MyQualifierLiteral()); 

//也可以通过字符串名称来查找: 
Object myBean = BeanProvider.getContextualReference("myBean", false); 

//通过字符串名称来查找,并且有预期的结果类型: 
MyBean myBean = BeanProvider.getContextualReference("myBean", false, MyBean.class); 

//解决一个给定类型的所有实例的上下文,如接口的所有实现 
List<MyServiceInterface> myServiceList = BeanProvider.getContextualReferences(MyServiceInterface.class, false); 

Since dependent scoped beans have a special role in CDI (you have to destroy them manually - especially if you get them via a manual lookup), you can also call the previous util method with an additional parameter to filter dependent scoped instances. 

Resolving All Contextual Instances of a Given Type without Dependent
Scoped Instances

List<MyServiceInterface> myServiceList = BeanProvider.getContextualReferences(MyServiceInterface.class, false, false);

Furthermore, it is possible to trigger the injection of fields of any given instance, if it was not done by the container (e.g. because the class is in a jar-file without beans.xml) and @Inject is used for 1-n fields.
Manually Inject Fields
BeanProvider.injectFields(myObject);

BeanManagerProvider

一般情况下,如果使用cdi的BeanManager,如下
@Inject 
private BeanManager beanManager; 

如果有特殊情况下无法使用@Inject,就可以使用下述代码获取BeanManager. 

BeanManager beanManager = BeanManagerProvider.getInstance().getBeanManager(); 

Type-safe ProjectStage

该deltaspike projectstage机制允许使用的配置和实现取决于你目前运行在服务器环境。
ProjectStage提供一种方式来影响项目的行为,这以一组预先定义好的阶段枚举为基础,而这些阶段可以通过上下文参数或者JNDI进行设置。比如说,产品化开发和检查期间可以在浏览器中显示更多的调试信息。已定义的阶段可以有产品化、开发、单元测试、系统测试及产品化扩展阶段,并将产品化扩展作为默认值。你可以在运行时通过调用ProjectStage来查询应用对象以获得相应的值。

可与cdi的替换注解@Alternative配合使用,更灵活.但我不会去用,感觉会搞的很复杂.

@Exclude,[不注册为cdi bean的类注解]

标注了@Exclude的类,cdi 容器选择忽略,不进行注册.其他地方将不能@Inject.也就是说标注类将不再是cdi bean.和seam中的@veto是一样的道理.
在任何情况下不注册为cdi Bean
@Exclude
public class NoBean
{
}
ProjectStage为Development的情况下将不注册为cdi bean.
@Exclude(ifProjectStage = ProjectStage.Development.class)
public class MyBean
{
}

ProjectStage如果不是Development,将不注册为cdi bean.

@Exclude(exceptIfProjectStage = ProjectStage.Development.class)
public class MyDevBean
{
}

下面是@Exclude基于项目xml配置来判断是否注册

@Exclude(onExpression = "db==prodDB")
public class DevDbBean
{
}

它还可以通过expressioninterpreter自定义表达式来判断

@Exclude(onExpression = "db eq prodDB", interpretedBy = SimpleExpressionInterpreter.class)
public class DevDbBean
{
}


public class SimpleExpressionInterpreter implements ExpressionInterpreter<String, Boolean>
{
    @Override
    public Boolean evaluate(String expression)
    {
        if(expression.contains(" eq "))
        {
            //...
        }
        //...
    }
}

apache也提供了与@Alternative配合使用.
说明:ProjectStage如果不是Development,并且bean.xml中也进行了配置,那么注册使用.

@Exclude(exceptIfProjectStage = ProjectStage.Development.class)
@Alternative
public class MyDevBean
{
}

自定义expressioninterpreter
默认情况下,只有一个非常简单的和有限的语法是支持。在实际工程中通常有非常具体的要求。因为它会支持他们大多数是非常复杂的,它是为用户实现一个优化的语法更容易。对于这样的情况,一个自定义的expressioninterpreter是必要的:

@Alternative
@Exclude(onExpression = "environment!=HSQL", interpretedBy = ConfigAwareExpressionInterpreter.class)
public class DevDbBean implements DbBean
{
}

public class ConfigAwareExpressionInterpreter implements ExpressionInterpreter<String, Boolean>
{
    public Boolean evaluate(String expression)
    {
        if (expression == null)
        {
            return false;
        }

        String[] values = expression.split("!=");

        if (values.length != 2)
        {
            throw new IllegalArgumentException("'" + expression + "' is not a supported syntax");
        }

        String configuredValue = ConfigResolver.getPropertyValue(values[0], null);

        //exclude if null or the configured value is different
        return configuredValue == null || !values[1].trim().equalsIgnoreCase(configuredValue);
    }
}


CDI Literals

通过继承抽象类'javax.enterprise.util.AnnotationLiteral',deltaSpike提供了很多有用的Literals[注解实例,不明者请先学习cdi/weld].
public abstract class PayByQualifier extends AnnotationLiteral<PayBy> implements PayBy {}

PayBy paybyCheque = new PayByQualifier() { public PaymentMethod value() { return CHEQUE; } };

DeltaSpike提供的Literals如下:

  • AlternativeLiteral
  • AnyLiteral
  • ApplicationScopedLiteral
  • ConversationScopedLiteral
  • DefaultLiteral
  • DependentScopeLiteral
  • ModelLiteral
  • NamedLiteral
  • NewLiteral
  • RequestedScopeLiteral
  • SessionScopeLiteral
  • Singleton
  • SpecializesLiteral
  • TypedLiteral


国际化

后台输出信息和properties文件的配合使用
以及更灵活的动态绑定Message,甚至更为灵活的自定义.
因实际里没有这方面的需求,个人只是粗略看了下.也比较简单.
请参考 http://deltaspike.apache.org/documentation/core.html#_messages_and_i18n 

Injecting Resources[简易读取系统配置文件]

deltaspike可以简单的使用API执行基本的资源/配置文件加载和读取。
@Inject
@InjectableResource("myfile.properties")
private InputStream inputStream;
这可以用来读取文件的路径,或在您的本地文件系统,使用两个默认的实现:classpathresourceprovider和fileresourceprovider。如果需要的话(例如数据库的LOB,NoSQL存储区),可以扩展injectableresourceprovider接口允许从其他来源的读取。

异常处理

Apache提供了一个系统全局的异常处理的手段.可以理解为拦截器+CDI event组合来拦截,处理系统所有的异常[你可以根据异常做更进一步更友好的提示信息].
Apache加入很多异常处理的注解,方便我们使用.方法也并不是很复杂.官方文档说明也比较明确.
http://deltaspike.apache.org/documentation/core.html#_exception_control 

eactivatable[停用自己的扩展类]

deltaspike允许您停用其自己的扩展。你只需要去实现你的classdeactivator。
如我们实现一个扩展:
public class CustomClassDeactivator implements ClassDeactivator
{


    private static final long serialVersionUID = 1L;


    @Override
    public Boolean isActivated(Class<? extends Deactivatable> targetClass)
    {
        if (targetClass.equals(SecurityExtension.class))
        {
            return Boolean.FALSE;
        }
        return null; //no result for the given class
    }
}
Now, we can use the file /META-INF/apache-deltaspike.properties (or any other ConfigSource) with the following key/value:
org.apache.deltaspike.core.spi.activation.ClassDeactivator=org.test.CustomClassDeactivator


Core - Utils

deltaspike提供许多实用静态工具类.有兴趣可以看看源码,但我看着感觉没啥用.....


你可能感兴趣的:(CDI,DeltaSpike)