2015-06-21 1 views
0

Итак, у меня есть служба, которую я запускаю, создавая экземпляр через фабрику, которая создает прокси-сервер, чтобы обрабатывать некоторые аннотации, которые у меня есть на службе. Поэтому мой вопрос заключается в следующем: существует ли способ с JavaEE, чтобы моя инъекция зависимостей создавала экземпляры упомянутой службы через фабрику, а не EJB, как правило, создаются сервером.Instantiate EJB Via Factory

Иначе ... есть ли другой способ, которым я мог бы управлять контейнером 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)); 
    } 
} 

Я хотел бы, если в сервлете я мог бы сделать что-то вроде этого:

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>"); 
    } 
} 

В выше, вы можете увидеть, как я мог бы быть инъекционного тест службы в мой сервлет. Но я бы хотел, чтобы контейнер EJB создавал новые экземпляры TestService с использованием фабрики вместо того, что обычно делает контейнер. Есть ли способ сделать это?

+0

Лучше добавить фрагмент кода, чтобы понять ваш вопрос n, чего вы на самом деле пытаетесь достичь. – OO7

ответ

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)); 
    } 
} 

И тогда в моем сервлета теперь я могу это сделать:

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>"); 
    } 
} 

Однако, если вы были попробуйте использовать это с сервисом TestService, отмеченным как управляемый компонент, вы получите исключение, потому что было бы неоднозначно, каким образом вы хотите создать его экземпляр, если вы не хотите использовать аннотацию @Qualifer. Я не хотел этого делать. Я просто хочу, чтобы везде это вводилось, чтобы использовать фабрику для создания экземпляра.

1

Невозможно напрямую перехватить @EJB в точке впрыска, но вы можете перехватить вызов метода по фактическому компоненту с помощью перехватчика EJB. Если вы можете переключиться на CDI @Inject на клиенте, вы можете использовать перехватчик CDI. В этот момент вы можете использовать способ создания CDI, чтобы иметь больший контроль над объектом, введенным в сервлет.

+0

Я на самом деле только что обнаружил, что могу делать то, что мне нужно с CDI (точно так же, как вы сказали). Маршрут, который я отправил с ним, тем не менее включал создание моей фабрики в качестве управляемого компонента, а затем добавление аннотации @Produces на мой заводский метод. Затем, когда изависимость вводится, она запускает его из фабричного метода вместо использования нового. – deusprogrammer

+0

@deusprogrammer Конечно, похоже, что это тоже сработает. Рад, что вы нашли решение. –

+0

И спасибо! Ваше руководство помогло мне! Я дам вам кредит за это =). – deusprogrammer