• HK2使用详解


    HK2介绍

    HK2是一个轻量级动态依赖注入框架,它是JSR-330的实现。

    组件

    在HK2组件模型中,一个组件的功能是通过服务接口-服务实现的模式声明的。一个HK2服务接口 标识并描述了一个构建模块或者应用程序扩展点。HK2服务实现实现了HK2服务接口。 #### 组件模型 (HK2)提供了一个模块系统和组件模型来建立复杂的软件系统。该模块系统负责实例化构成应用程序功能的类。HK2运行时通过创建对象来填充该模块系统。模块系统通过以下方式装配对象: - 实例化一个新的对象注入到需要这个对象的对象中。 - 为这个对象注入所需的配置信息。 - 使新建的对象可用,这样这些对象就可以注入到其他需要这些对象的对象中。

    服务

    一个HK2服务(服务接口)标识并描述了一个构建模块或者应用程序扩展点。服务是一个普通的Java对象(POJO)具有以下特点:

    • 该对象(类)实现了一个接口
    • 对象(类)应该在JAR的META-INF/services文件中声明

    作用范围

    @Singleton

    生命周期

    组件可以在初始化和销毁事件发生过程中,添加切面逻辑,实现接口:org.jvnet.hk2.component.PostConstruct 和 org.jvnet.hk2.component.PreDestroy。 > 实现接口还是使用注解,可以根据性能决定。

    PostConstruct.postConstruct() :这个方法在组件初始化并且组件的依赖被注入后调用。 PreDestroy.preDestroy() :这个方法在组件从系统移除前调用。

    @Service(name="")
    public class MyContainer implements Container, PostConstruct, PreDestroy {
        @Inject
        Logger logger;
        ...
        public void postConstruct() {
            logger.info("Starting up.");
        }
    
        public void preDestroy() {
            logger.info("Shutting down.");
        }
    }
    

    定义服务

    #### 默认实现 ```java //默认只有一种实现的情况,接口定义: @Contract public interface Foo { } //具体业务在实现类中 @Service public class FooImpl implements Foo { } ```

    服务命名

    //为了区分相同的接口的不同实现,你可以给你的服务命名。如下例子:
    @Contract
    public interface Book {
    }
    
    @Service @Named
    public class Moby implements Book {
    }
    
    @Service @Named
    public class ParadiseLost implements Book {
    }
    

    限定服务

    //服务也可以被注解限定调用。这个注解需要标注@Qualifier注解,看例子:
    @Contract
    public interface Color {
    }
    
    @Service @Blue
    public class BlueColor implements Color {
    }
    
    @Service @Red
    public class RedColor implements Color {
    }
    //Blue注解的实现
    @Qualifier
    @Retention(RUNTIME)
    @Target( { TYPE, METHOD, FIELD, PARAMETER })
    public @interface Blue {
    }
    

    注入服务

    #### 基础注入 ```java //作为成员变量注入: @Inject ConfigService config; //setter上注入 @Inject public void set(ConfigService config) {...} //也可通过构造函数注入 @Service public class FooImpl implements Foo { private final Book book;

    @Inject
    public FooImpl(Book book) {
    // constructor injected!
    this.book = book;
    }
    }

    
    #### 名称注入(Injection by name)
    ```java
    //需要给服务命名,然后通过名称才能注入,看例子:
    @Service
    public class FooImpl implements Foo {
      @Inject @Named("Moby")
      private Book mobyDick;
    
      @Inject @Named("ParadiseLost")
      private Book paradiseLost;
    }
    

    限定注入(Injection by qualifier)

    //限定服务,按照以下方式注入,看例子:
    @Service
    public class ColorMixer {
        private Color red;
        private Color blue;
    
        @Inject
        private void addPrimaries(@Red Color red, @Blue Color blue) {
          this.red = red;
          this.blue = blue;
       }
    }
    

    Provider注入

    很多情况下,注入一个服务的Provider要比注入服务本身要好,因为系统可能延时创建服务,直到Provider的get方法被调用。

    @Service
    public class ColorMixer {
        @Inject @Red
        private Provider<Color> redProvider;
    
        @Inject @Blue
        private Provider<Color> blueProvider;
    }
    //服务中可以在需要时再调用
    @Service
    public class ColorMixer {
        ...
    
        public Color makePurple() {
          return mix(redProvider.get(), blueProvider.get());
        }
    }
    

    IterableProvider注入

    通常情况下,一个contract会有多个实现,如果要访问所有的实现,就需要使用IterableProvider。

    @Service
    public class Library {
        @Inject
        private IterableProvider<Book> allBooks;
    
        public LinkedList<Book> getAllBooks() {
            LinkedList<Book> retVal = new LinkedList<Book>();
    
            for (Book book : allBooks) {
                retVal.add(book);
            }
    
            return retVal;
        }
    }
    //另外一个特性,我们可以使用named获取一个特定的实现。
    @Service
    public class Library {
        @Inject
        private IterableProvider<Book> allBooks;
    
        public Book findBook(String name) {
            return allBooks.named(name).get();
        }
    }
    

    Iterable注入

    Iterable can be used as an injection point rather than IterableProvider.

    @Service
    public class Library {
        @Inject
        private Iterable<Book> allBooks;
    
        public LinkedList<Book> getAllBooks() {
            LinkedList<Book> retVal = new LinkedList<Book>();
    
            for (Book book : allBooks) {
                retVal.add(book);
            }
    
            return retVal;
        }
    }
    

    总结

    如果对底层实现感兴趣,不如去看看这个kunJ,当然,给个star也是极好的。

  • 相关阅读:
    指针理解
    http和https区别
    js 日历控件
    Linux 目录详解!(转)
    互换位置输出
    晨时跌荡起伏的心情
    c++冒泡排序
    游标使用
    防止Sql注入
    ssl加密原理
  • 原文地址:https://www.cnblogs.com/lknny/p/7490048.html
Copyright © 2020-2023  润新知