2013-08-27 52 views
16

Tôi muốn tạo một lớp có đối tượng có thể được tiêm bằng chú thích @Context (hoặc chú thích tùy chỉnh tốt hơn cho các trường hợp tôi cần chuyển đối số cho chú thích) vào phương pháp tài nguyên. Ở Jersey 1. * Tôi đã sử dụng InjectableProvider (trong trường hợp của tôi cùng với AbstractHttpContextInjectable). Những gì tôi đang cố gắng đạt được là một cái gì đó như @Auth [1] từ dropwizard (sử dụng Jersey 1.7).Jersey 2. *. Làm thế nào để thay thế InjectableProvider và AbstractHttpContextInjectable của Jersey 1. *

Khả năng phun của Jersey đã được thay thế bằng HK2 theo như tôi biết và tôi không thể tìm thấy bất kỳ ví dụ nào về những gì tôi mô tả.

Chỉnh sửa: Xem this question để biết thêm các sự cố mà tôi gặp phải khi cố gắng làm theo hướng dẫn của Michal.

Trả lời

20

Bạn cần triển khai giao diện InjectionResolver<T> từ HK2. Hãy nhìn vào hiện thực hiện được hiện diện trong không gian làm việc Jersey:

Khi bạn có điều này, bạn cần mở rộng AbstractBinder từ HK2 và liên kết InjectionResolver của bạn thông qua số #configure() phương pháp:

public class MyResolverBinder extends AbstractBinder { 

    @Override 
    protected void configure() { 
     bind(MyInjectionResolver.class) 
       .to(new TypeLiteral<InjectionResolver<MyAnnotation>>() {}) 
       .in(Singleton.class); 
    } 
} 

... và đăng ký một thể hiện của chất kết dính này trong lớp ứng dụng của bạn (hoặc thông qua feature):

Feature:

public class MyFeature implements Feature { 

    @Override 
    public boolean configure(final FeatureContext context) { 
     context.register(new MyResolverBinder()); 
     return true; 
    } 
} 

đăng ký MyFeature vào Application:

public class JaxRsApplication extends Application { 

    @Override 
    public Set<Class<?>> getClasses() { 
     final HashSet<Class<?>> classes = new HashSet<Class<?>>(); 
     classes.add(MyFeature.class); 
     // Register other providers or resources. 
     return classes; 
    } 
} 

đăng ký MyResolverBinder hoặc Feature trong ResourceConfig

new ResourceConfig() 
     // Register either MyFeature 
     .register(MyFeature.class) 
     // or MyResolverBinder 
     .register(new MyResolverBinder()) 
     // Register other providers or resources 
     .packages("my.package"); 
+0

Cảm ơn! Điều đó dường như chính xác những gì tôi cần. – TheCuriousOne

+0

Michal, tôi đã cố gắng làm theo hướng dẫn của bạn, nhưng tôi đã gặp phải một cảnh báo lạ "... Phương thức HTTP GET ... không nên dùng bất kỳ thực thể nào". Tôi không chắc chắn phải làm gì (xem chỉnh sửa câu hỏi của tôi để biết thêm chi tiết).Bạn có ý tưởng nào về những gì có thể gây ra nó không? Cảm ơn. – TheCuriousOne

+0

Cảm ơn câu trả lời. Tuy nhiên, nó không rõ ràng với tôi làm thế nào để tạo ra một đối tượng được đưa ra, nói, 'ContainerRequestContext' và làm thế nào để xử lý đúng đối tượng được tiêm, ví dụ, bằng cách gọi' close() '. Tôi không thể tìm thấy bất kỳ ví dụ trực tuyến nào, bạn có đề xuất nào không? –

3

Cung cấp một thực hiện InjectionResolver chỉ giúp với tiêm, không phải khi giải quyết các giá trị cho các tham số của một phương pháp tài nguyên.

Ít nhất với Jersey 2.11, bạn cần xác định ValueFactoryProvider được chú thích với @Provider.

@Provider 
public class MyValueFactoryProvider implements ValueFactoryProvider { 

    @Inject 
    private MyFactory factory; 

    @Override 
    public Factory<?> getValueFactory(Parameter parameter) { 
     if (parameter.getAnnotation(MyAnnotationParam.class) != null) { 
      return factory; 
     } 

     return null; 
    } 

    @Override 
    public PriorityType getPriority() { 
     return Priority.NORMAL; 
    } 

} 

Nếu bạn cũng muốn nhận giá trị được chèn vào, ví dụ: thành viên và thông số hàm tạo, thì InjectionResolver hoạt động tốt.