在 这篇帖子 的评论线程中,Bill 让我想起了困扰我一段时间的问题。
问题是,有一些类型的 依赖对象
(在 Web Beans 的意义下)需要了解它们注入的对象或注入点的某些信息,才能执行它们的操作。例如@Dependent作用域
- Logger的日志类别取决于拥有它的对象的类别HTTP 参数或头值注入取决于注入点指定的参数或头名称
- EL 表达式求值结果的注入取决于注入点指定的表达式
- 注入
我提出的解决方案是允许将一个特殊的元数据对象注入到任何注入的依赖对象中。
(请注意,此功能专门用于@Dependent作用域 Web Beans - 具有正常作用域的对象在许多客户端和许多注入点之间共享,因此它们的行为不能依赖于任何与客户端相关的事项。)
让我们来看一个例子
class LogFactory { @Produces Logger createLogger(InjectionPoint injectionPoint) { return Logger.getLogger(injectionPoint.getMember().getDeclaringClass().getName()); } }
这个巧妙的小生产者方法允许您注入具有正确日志类别的 JDK的日志类别取决于拥有它的对象的类别而不是输入
Logger log = Logger.getLogger(MyClass.class.getName());
您可以写入
@Current Logger log;
这更短,且不太容易受到重构问题的影响。
不相信?好吧,让我们看看第二个例子...
要注入 HTTP 参数,我们需要定义一个绑定类型
@BindingType @Retention(RUNTIME) @Target({TYPE, METHOD, FIELD, PARAMETER}) public @annotation HttpParam { @NonBinding public String value(); }
我们将在注入点使用此绑定类型如下
@HttpParam("username") String username; @HttpParam("password") String password;
以下生产者方法执行工作
class HttpParams @Produces @HttpParam("") String getParamValue(ServletRequest request, InjectionPoint ip) { return request.getParameter(ip.getAnnotation(HttpParam.class).value()); } }
我想这些内容主要用于框架类型开发,但也可能有其他应用。
那么,将此功能添加到 Web Beans 中有多难?一点也不难!Web Beans 规范将定义以下 API
public interface InjectionPoint { public Type getType(); public Set<Annotation> getBindingTypes(); public Object getInstance(); public Bean<?> getBean(); public Member getMember(): public <T extends Annotation> T getAnnotation(Class<T> annotation); public Set<T extends Annotation> getAnnotations(); }
并且Web Bean管理器需要提供实现此接口的内建Web Bean。
你怎么看?