所以我有一个服务,我通过创建代理的工厂实例化它,以便它可以处理我在服务上的一些注释。所以我的问题是这个...... JavaEE是否有办法让我的依赖注入通过工厂实例化所述服务的实例,而不是EJB通常由服务器实例化。
否则......是否有另一种方法可以指示Servlet或EJB容器为我处理注释?就像一个类似的螺栓,可以有代码来处理带注释的类/方法/字段的反射分析?
如果这个问题很难理解,我很抱歉,我很难搞清楚如何问这个问题。以下是可用于实例化服务的工厂示例(通过代理)。
package com.trinary.test.service;
import java.lang.reflect.Proxy;
import com.trinary.security.owasp.proxy.OWASPMethodValidatorProxy;
public class TestServiceFactory {
Class<?>[] interfaces = {TestService.class};
public TestService createESignService() throws IllegalArgumentException, InstantiationException, IllegalAccessException {
return (TestService)Proxy.newProxyInstance(
this.getClass().getClassLoader(),
interfaces,
new OWASPMethodValidatorProxy<TestService>(TestServiceImpl.class));
}
}
我很乐意,如果在servlet中我可能会做这样的事情:
package com.trinary.test.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.trinary.test.service.TestService;
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = -1778574173539761350L;
@EJB protected TestService testService;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("PATH: " + req.getPathInfo());
// ...
resp.setContentType("text/html");
resp.getWriter().append("<html><h1>TESTY TEST!</h1></html>");
}
}
在上面你可以看到我如何将测试服务注入到我的servlet中。但我希望EJB容器使用工厂实例化TestService的新实例,而不是容器通常这样做。有没有办法做到这一点?
答案 0 :(得分:1)
在注入点无法直接拦截@EJB
,但您可以使用EJB拦截器拦截实际bean上的方法调用。如果您可以在客户端切换到CDI @Inject
,那么您可以使用CDI拦截器。此时,您可以使用CDI生成器方法来更好地控制注入到servlet中的对象。
答案 1 :(得分:0)
我刚刚发现了如何解决我的问题。首先,作为一个评论者指出,我选择了CDI而不是EJB(我需要了解两者之间的差异,以及大多数应用服务器是否支持它)。
其次我在我工厂的方法中使用了@Produces注释,如下所示:
import java.lang.reflect.Proxy;
import javax.ejb.Stateless;
import javax.enterprise.inject.Default;
import javax.enterprise.inject.Produces;
import com.trinary.security.owasp.proxy.OWASPMethodValidatorProxy;
@Local
public class TestServiceFactory {
Class<?>[] interfaces = {TestService.class};
@Produces
@Default
public TestService createESignService() throws IllegalArgumentException, InstantiationException, IllegalAccessException {
return (TestService)Proxy.newProxyInstance(
this.getClass().getClassLoader(),
interfaces,
new OWASPMethodValidatorProxy<TestService>(TestServiceImpl.class));
}
}
然后在我的servlet中,我现在可以这样做:
import java.io.IOException;
import javax.inject.Inject;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.trinary.test.service.TestService;
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = -1778574173539761350L;
@Inject TestService testService;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
System.out.println("PATH: " + req.getPathInfo());
testService.method(...);
// ...
resp.setContentType("text/html");
resp.getWriter().append("<html><h1>TESTY TEST!</h1></html>");
}
}
但是,如果您尝试将此服务与标记为托管bean的服务TestService一起使用,则会出现异常,因为除非您想使用@Qualifer注释,否则您希望实例化它的方式不明确。我当选不。我只想在任何地方注入这些来使用工厂进行实例化。