使用@Producer方法选择CDI @Qualifier

时间:2014-05-13 16:20:37

标签: java cdi

我有一个带有安全管理器的Java EE 7 Web应用程序,使用户能够使用' Roles'进行身份验证。在整个应用程序中,有些服务的实现取决于用户'角色'

最初我有一个由单个类实现的接口,在该类的每个方法中我确定了什么'角色'主题已经并使用开关来执行相应的代码。

为了改进这一点,我现在创建了几个接口实现类,并使用相应的@Qualifier进行装饰,每个类都注定要映射到特定的“角色”。

为了简单起见,我们可以说限定符为@Administrator@User,并且我在整个应用程序中有30个类需要这个'角色'基于实施。在每种情况下,我总是希望管理员'使用@Administrator装饰实施和'用户'使用@User装饰实现。

我不想编写30个生产者工厂类,因为这似乎效率低下(而且错误!)。我想要实现的是一个工厂总是选择相应的限定符而不管其类型。

为清晰起见,这是一个非常简化的代码版本。

接口:

public interface MyInterface {
...
}

public interface MyInterface2 {
...
}

最初的方法是使用开关(简化为if else here)

public class AdministratorMyInterface implements MyInterface {

    if (role.equals("Administrator")) {
       ... execute administrator version ...
    } else {
       ... execute user version ...
    }

}

public class AdministratorMyInterface2 implements MyInterface2 {

    if (role.equals("Administrator")) {
       ... execute administrator version ...
    } else {
       ... execute user version ...
    }

}

新目标是单独实施。一个与管理员一起使用。

@Administrator
public class AdministratorMyInterface implements MyInterface {

... implementations specific to administrators ...

}

@Administrator
public class AdministratorMyInterface2 implements MyInterface2 {

... implementations specific to administrators ...

}

具有用户角色的用户使用的某些界面实现:

@User
public class UserMyInterface implements MyInterface {

... implementations specific to users ...

}

@User
public class UserMyInterface2 implements MyInterface2 {

... implementations specific to users ...

}

我现在需要一种方法,以便如果管理员执行代码,他们总是实现用@Administrator修饰的实现。

这可能吗?有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

您可以为MyInterface编写一个生成器,该实例将注入实例,然后选择()s相应的实现。

看看这个优秀的例子:http://www.byteslounge.com/tutorials/java-ee-cdi-programmatic-dependency-disabiguation-example-injection-point-inspection

  @Produces
  public MyInterface createService(
    @Any Instance<MyInterface> instance, InjectionPoint ip){
    // you will need to determine if @Admin or @User should be used ... I dont know your user handling, so this is custom coding.
    return instance.select(annotation).get();
  }