另一个出色的便携式扩展

发布者:    |       CDI Weld

这是一个CDI便携式扩展,它从属性文件中读取值并配置Java EE组件的字段。在Java EE 6中,这适用于任何支持注入的Java EE组件,包括servlets、EJBs、托管bean、拦截器等。

在此示例中,例如org.mydomain.blog.Blogger的属性位于名为org/mydomain/blog/Blogger.properties的资源中,并且属性的名称必须与要配置的字段的名称匹配。因此Blogger.properties将包含

firstName=Gavin
lastName=King

该便携式扩展通过包装容器InjectionTarget并从inject()方法中设置字段值。

public class ConfigExtension implements Extension {

        <X> void processInjectionTarget(ProcessInjectionTarget<X> pit) {
                
            final InjectionTarget<X> it = pit.getInjectionTarget();
        final Map<Field, Object> configuredValues = new HashMap<Field, Object>();
        
        AnnotatedType<X> at = pit.getAnnotatedType();
        
        String propsFileName = at.getClass().getSimpleName() + ".properties";
        InputStream stream = at.getJavaClass().getResourceAsStream(propsFileName);
        if (stream!=null) {
            
            try {
                Properties props = new Properties();
                props.load(stream);
                for (Map.Entry<Object, Object> property : props.entrySet()) {
                    String fieldName = property.getKey().toString();
                    Object value = property.getValue();
                    try {
                        Field field = at.getJavaClass().getField(fieldName);
                        field.setAccessible(true);
                        if ( field.getType().isAssignableFrom( value.getClass() ) ) {
                            configuredValues.put(field, value);
                        }
                        else {
                            //TODO: do type conversion automatically
                            pit.addDefinitionError( new InjectionException("field is not of type String: " + field ) );
                        }
                    }
                    catch (NoSuchFieldException nsfe) {
                        pit.addDefinitionError(nsfe);
                    }
                }
            }
            catch (IOException ioe) {
                pit.addDefinitionError(ioe);
            }
            finally {
                stream.close();
            }
        }
        
        InjectionTarget<X> wrapped = new InjectionTarget<X>() {

            @Override
            public void inject(X instance, CreationalContext<X> ctx) {
                it.inject(instance, ctx);
                for (Map.Entry<Field, Object> configuredValue: configuredValues.entrySet()) {
                    try {
                        configuredValue.getKey().set(instance, configuredValue.getValue());
                    }
                    catch (Exception e) {
                        throw new InjectionException(e);
                    }
                }
            }

            @Override
            public void postConstruct(X instance) {
                it.postConstruct(instance);
            }

            @Override
            public void preDestroy(X instance) {
                it.dispose(instance);
            }

            @Override
            public void dispose(X instance) {
                it.dispose(instance);
            }

            @Override
            public Set<InjectionPoint> getInjectionPoints() {
                return it.getInjectionPoints();
            }

            @Override
            public X produce(CreationalContext<X> ctx) {
                return it.produce(ctx);
            }
            
        };
        
        pit.setInjectionTarget(wrapped);
        
    }
    
}

该便携式扩展必须部署在一个包含名为META-INF/services/javax.enterprise.inject.spi.Extension的jar文件中,该文件包含完全限定的扩展类名称。


返回顶部