2013-11-14 4 views
0

У меня есть приложение, которое USSE JavaFX 2, и я хочу, чтобы убедиться, что определенный код вызывается в каждом методе интерфейса:Не удается перехватить Pointcut с Spring AOP

public interface IControladorDialogoPrincipal extends IControladorDialogo{ 
    @FXML 
    void abrirCaixa(ActionEvent e); 

    @FXML 
    void fecharCaixa(ActionEvent e); 

    @FXML 
    void novaPreVenda(ActionEvent evento); 

    @FXML 
    void mesclarPreVenda(ActionEvent evento); 
} 

Это часть класс, который реализует интерфейс выше:

public class ControladorDialogoPrincipal extends ControladorDialogoSubmeter implements IProcessamentoListener, IControladorDialogoPrincipal { 

    @FXML 
    private StackPane painelPrincipal; 
    @FXML 
    private BorderPane painelConteudo; 
    @FXML 
    private BorderPane painelProgresso; 
    @Autowired 
    private ControladorExecucaoTarefa controladorExecucaoTarefa; 
    @Autowired 
    private ControladorDialogoMensagem dialogoMensagem; 
    @Autowired 
    private RecuperadorBeanSpring recuperadorBean; 

    @Override 
    protected void configurarElementos() { 
     stage.setOnCloseRequest(new EventHandler<WindowEvent>() { 
      public void handle(WindowEvent e) { 
       System.exit(0); 
      } 
     }); 
     stage.setWidth(800); 
     stage.setHeight(600); 
     painelProgresso.toBack(); 
     painelProgresso.setVisible(false); 
    } 
    . 
    . 
    . 
} 

базовый класс для всех ControladorDialogo * является это абстрактный класс:

public abstract class ControladorDialogo implements IControladorDialogo { 

    private URL modelo; 
    protected Stage stage; 
    protected String titulo = ""; 
    protected List<String> estilos = new ArrayList<String>(); 
    protected Logger logger = LoggerFactory.getLogger(this.getClass()); 

    @Override 
    public final void init() { 
     try { 
      stage = new Stage(); 
      definirTitulo(titulo); 
      stage.setScene(carregarCena()); 
      stage.initModality(Modality.WINDOW_MODAL); 
      configurarElementos(); 
     } catch (IOException e) { 
      logger.error("Erro ao tentar carregar arquivo FXML: ", e); 
     } 
    } 

    protected final Scene carregarCena() throws IOException { 
     Parent root = (Parent) SpringFXMLLoader.load(modelo.openStream(), this); 
     Scene cena = new Scene(root); 
     cena.getStylesheets().addAll(estilos); 
     return cena; 
    } 

    protected void configurarElementos() { 
    } 

    protected void definirTitulo(String titulo) { 
     if (stage != null) { 
      this.titulo = titulo; 
      stage.setTitle(titulo); 
     } 
    } 

    @Override 
    public void abrir() { 
     stage.show(); 
    } 

    @Override 
    public void fechar() { 
     stage.close(); 
    } 

    @Override 
    public void setModelo(URL modelo) { 
     this.modelo = modelo; 
    } 

    @Override 
    public void setEstilos(List<String> estilos) { 
     this.estilos = estilos; 
    } 
} 

Вот конфиг весной по АОП и Конкретизация ControladorDialogoPrincipal боба:

<bean id="controladorDialogoPrincipal" class="com.hrgi.pdv.controladores.gui.dialogos.ControladorDialogoPrincipal" 
     init-method="init"> 
    <property name="modelo" value="classpath:gui/dialogoPrincipal.fxml"/> 
    <property name="estilos" ref="estilos"/> 
</bean> 

<util:list id="estilos" list-class="java.util.ArrayList"> 
    <value>/css/preVenda.css</value> 
</util:list> 

<aop:config> 
    <aop:aspect ref="dataSource"> 
     <aop:pointcut id="todosOsMetodosIControladorDialogoPrincipal" expression="execution(* com.hrgi.pdv.controladores.gui.dialogos.IControladorDialogoPrincipal.*(..))"/> 
     <aop:before method="travarConexao" pointcut-ref="todosOsMetodosIControladorDialogoPrincipal"/> 
    </aop:aspect> 
</aop:config> 

Я хочу вызвать метод «travarConexao» этого класса:

public class RoutingDataSource extends AbstractRoutingDataSource implements Runnable { 
    . 
    . 
    . 
    private void definirConexaoAtual() { 
     if (conexaoTravada && conexaoAtual.equalsIgnoreCase("secundario")) 
      return; 
     DataSource principal = (DataSource) fontesDeDados.get("principal"); 
     if (verificarConexao(principal)) { 
      synchronized (conexaoAtual) { 
       conexaoAtual = "principal"; 
      } 
     } else { 
      synchronized (conexaoAtual) { 
       conexaoAtual = "secundario"; 
      } 
     } 
    } 

    private boolean verificarConexao(DataSource principal) { 
     try { 
      Connection conexao = principal.getConnection(); 
      Statement statement = conexao.createStatement(); 
      return statement.executeQuery("SELECT 1") != null; 
     } catch (Exception e) { 
      return false; 
     } 
    } 

    public void travarConexao() { 
     System.out.println("\n\ncalled!!\n\n"); 
     definirTravaDeConexao(true); 
    } 

    private void definirTravaDeConexao(Boolean trava) { 
     synchronized (conexaoTravada) { 
      conexaoTravada = trava; 
     } 
     definirConexaoAtual(); 
    } 
    . 
    . 
    . 
} 

Может кто-нибудь объяснить мне, почему это метод никогда не называется?

+0

Можете ли вы разместить больше в своем контексте приложения или файле конфигурации пружины, чтобы получить полноценное представление об этом? –

+0

Привет @DiegoJimeno, я добавил дополнительную информацию на вопрос – brevleq

ответ

0

Проблема была в плохом состоянии. После того, как заметил, что ни один точек вставки я не tryied работал (ни самый простой), я изменил от чистого Spring AOP в AspectJ с весны:

<aop:aspectj-autoproxy/> 
<context:spring-configured/> 

<bean class="com.hrgi.pdv.InterceptadorTravamentoConexao" scope="prototype"> 
    <property name="routingDataSource" ref="dataSource"/> 
</bean> 

срез точек был перемещен в аннотации в определенном новом классе:

@Aspect 
@Configurable 
public class InterceptadorTravamentoConexao { 

    private RoutingDataSource routingDataSource; 

    @Before("execution(* com.hrgi.pdv.controladores.gui.dialogos.IControladorDialogoPrincipal.*(..))") 
    public void travarConexao(){ 
     routingDataSource.travarConexao(); 
    } 

    public void setRoutingDataSource(RoutingDataSource routingDataSource) { 
     this.routingDataSource = routingDataSource; 
    } 
} 

Добавлено слишком некоторые конфигурации для AspectJ-компилятор в мавена:

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>aspectj-maven-plugin</artifactId> 
    <version>1.4</version> 
    <configuration> 
     <showWeaveInfo>true</showWeaveInfo> 
     <source>1.7</source> 
     <target>1.7</target> 
     <Xlint>ignore</Xlint> 
     <complianceLevel>1.7</complianceLevel> 
     <encoding>UTF-8</encoding> 
     <verbose>true</verbose> 
     <aspectLibraries> 
      <aspectLibrary> 
       <groupId>org.springframework</groupId> 
       <artifactId>spring-aspects</artifactId> 
      </aspectLibrary> 
     </aspectLibraries> 
    </configuration> 
    <executions> 
     <execution> 
      <goals> 
       <goal>compile</goal> 
       <goal>test-compile</goal> 
      </goals> 
     </execution> 
    </executions> 
    <dependencies> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjrt</artifactId> 
      <version>1.7.3</version> 
     </dependency> 
     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjtools</artifactId> 
      <version>1.7.3</version> 
     </dependency> 
    </dependencies> 
</plugin> 

Сейчас она работает.

1

Есть случаи, когда вы не можете заставить Spring AOP работать с JavaFX 2, потому что компоненты JavaFX 2 используют множество внутренних конечных классов, и вы не можете эффективно внедрять прокси внутри CGLIB или Javassist. На самом деле я не пробовал с AspectJ, но я считаю, что это та же проблема.

Подводя итог, если вы пытаетесь перехватить метод, который находится внутри пользовательского компонента JavaFX (например, расширяет GridPane), вы не сможете этого сделать (или, может быть, вам повезло, t для всех методов).

Если вы пытаетесь перехватить метод с помощью контроллера JavaFX (который не расширяет класс javafx), убедитесь, что Spring знает контроллер через свой контекст (проверьте интеграцию Spring JavaFX). Наконец, если это нормально, попробуйте использовать CGLIB с:

<aop:config proxy-target-class="false"/> 
<aop:aspectj-autoproxy proxy-target-class="false"/> 
+0

Привет, @enbeni, есть ли способ обойти это ограничение? Вызовите travarConexao во всех методах, которые ему нужны, это действительно плохо. – brevleq

+0

@brevleq Я точно не знаю, что вам нужно, вы проверили, что ваша конфигурация AOP правильная с базовыми pointcuts на ванильных весенних бобах? Попробуйте определить базовый HelloWorldService весной и добавьте pointcut для одного метода, посмотрите, что произойдет потом. Если это не работает, то javafx не является проблемой, вероятно, проблемой зависимости/конфигурации (с или без cglib). – zenbeni

Смежные вопросы