6

Tôi đang sử dụng Java EE 6 và cần tải cấu hình từ tệp ".properties". Có cách nào được khuyến nghị (thực hành tốt nhất) để tải các giá trị từ tệp cấu hình bằng cách sử dụng tiêm phụ thuộc không? Tôi đã tìm thấy chú thích cho điều này trong Spring, nhưng tôi đã không tìm thấy chú thích "chuẩn" cho Java EE.Chèn phụ thuộc bằng cách sử dụng tệp ".properties"

anh chàng này đã phát triển một giải pháp từ đầu:

http://weblogs.java.net/blog/jjviana/archive/2010/05/18/applicaction-configuration-java-ee-6-using-cdi-simple-example

"Tôi không thể tìm thấy một ví dụ đơn giản về cách cấu hình ứng dụng của bạn với CDI bằng cách đọc cấu hình các thuộc tính từ một tập tin. .. "

Nhưng tôi tự hỏi nếu có một cách tiêu chuẩn hơn thay vì tạo nhà máy cấu hình ...

Trả lời

1

Mặc dù nó không bao gồm chính xác câu hỏi của bạn, this part của tài liệu Weld có thể được bạn quan tâm.

Có đề cập đến điều này - không, không có cách tiêu chuẩn để tiêm các tài nguyên tùy ý/tệp tài nguyên. Tôi đoán nó chỉ đơn giản là vượt quá phạm vi của một spec để tiêu chuẩn hóa yêu cầu phụ thuộc cao như vậy tùy chỉnh (Spring là không có đặc điểm kỹ thuật, họ chỉ có thể thực hiện bất cứ điều gì họ thích). Tuy nhiên, những gì CDI cung cấp là một cơ chế mạnh mẽ (hay còn gọi là an toàn) để chèn các bean đang giữ cấu hình ở một bên, và một cơ chế sản xuất linh hoạt để đọc và tạo ra các bean như vậy ở phía bên kia. Chắc chắn đây là cách được đề nghị mà bạn đã hỏi.

Cách tiếp cận mà bạn đang liên kết đến chắc chắn là một cách khá tốt - mặc dù nó có thể là quá nhiều cho nhu cầu của bạn, tùy thuộc vào loại tài sản bạn dự định tiêm.

Một cách tiếp cận CDI-ish sẽ là phát triển một phần mở rộng CDI (có thể đóng gói độc đáo tất cả các lớp bắt buộc) và triển khai nó độc lập với các dự án của bạn. Tất nhiên bạn cũng có thể đóng góp cho số CDI-extension catalog hoặc thậm chí Apache Deltaspike.

+0

"Mùa xuân là không có đặc điểm kỹ thuật, họ có thể chỉ đơn giản thực hiện bất cứ điều gì họ thích "- vâng, nhưng cụ thể những thứ không đến từ thiên đàng. Ai đó đã viết nó, giống như ai đó đã viết Spring. –

1

Cách "tiêu chuẩn" duy nhất để thực hiện việc này là sử dụng vòng loại với thành viên chú thích không ràng buộc và đảm bảo rằng tất cả các loại tiêm của bạn đều bị phụ thuộc vào phạm vi. Sau đó, trong nhà sản xuất của bạn, bạn có thể nhận được một tổ chức của InjectionPoint và lấy chìa khóa ra khỏi vòng loại tại điểm tiêm. Bạn sẽ muốn một cái gì đó như thế này:

@Qualifier 
public @interface Property { 
    @Nonbinding String value default ""; 
} 

... 
@Inject @Property("myKey") String myKey; 


... 
@Produces @Property public String getPropertyByKey(InjectionPoint ip) { 
    Set<Annotation> qualifiers = ip.getQualifiers 

    // Loop through qualifers looking for Property.class save that off 
    return ResourceBundle.getBundle(...).getString(property.key); 
} 

Có một số cải tiến bạn có thể làm với mã đó, nhưng nó cũng đủ để bạn bắt đầu đi đúng hướng.

1

Xem @ConfigProperty của Apache DeltaSpike

3

Cấu hình chú thích

package com.ubiteck.cdi; 
import java.lang.annotation.Retention; 
import java.lang.annotation.RetentionPolicy; 
import javax.enterprise.util.Nonbinding; 
import javax.inject.Qualifier; 

@Qualifier 
@Retention(RetentionPolicy.RUNTIME) 
public @interface InjectedConfiguration { 
    /** 
    * Bundle key 
    * @return a valid bundle key or "" 
    */ 
    @Nonbinding String key() default ""; 
    /** 
    * Is it a mandatory property 
    * @return true if mandator 
    */ 
    @Nonbinding boolean mandatory() default false; 
    /** 
    * Default value if not provided 
    * @return default value or "" 
    */ 
    @Nonbinding String defaultValue() default ""; 
} 

Nhà máy cấu hình có thể trông giống như:

import java.text.MessageFormat; 
import java.util.MissingResourceException; 
import java.util.ResourceBundle; 
import javax.enterprise.inject.Produces; 
import javax.enterprise.inject.spi.InjectionPoint; 

public class ConfigurationInjectionManager { 
    static final String INVALID_KEY="Invalid key '{0}'"; 
    static final String MANDATORY_PARAM_MISSING = "No definition found for a mandatory configuration parameter : '{0}'"; 
    private final String BUNDLE_FILE_NAME = "configuration"; 
    private final ResourceBundle bundle = ResourceBundle.getBundle(BUNDLE_FILE_NAME); 

    @Produces 
    @InjectedConfiguration 
    public String injectConfiguration(InjectionPoint ip) throws IllegalStateException { 
     InjectedConfiguration param = ip.getAnnotated().getAnnotation(InjectedConfiguration.class); 
     if (param.key() == null || param.key().length() == 0) { 
      return param.defaultValue(); 
     } 
     String value; 
     try { 
      value = bundle.getString(param.key()); 
      if (value == null || value.trim().length() == 0) { 
       if (param.mandatory()) 
        throw new IllegalStateException(MessageFormat.format(MANDATORY_PARAM_MISSING, new Object[]{param.key()})); 
       else 
        return param.defaultValue(); 
      } 
      return value;    
     } catch (MissingResourceException e) { 
      if (param.mandatory()) throw new IllegalStateException(MessageFormat.format(MANDATORY_PARAM_MISSING, new Object[]{param.key()})); 
      return MessageFormat.format(INVALID_KEY, new Object[]{param.key()}); 
     } 
    } 

Tutorial with explanation and Arquillian test

+0

cảm ơn! làm thế nào chúng ta có thể thay đổi BUNDLE_FILE_NAME theo chương trình ở đây? Ví dụ chương trình A a có thể sử dụng "a.properies" và chương trình B "b.các thuộc tính "nhưng muốn chia sẻ mã này. –

+0

làm thế nào để bạn xác định tệp đang được tiêm và nó đọc nó từ đâu? – f1wade