2013-11-14 53 views
0

我有USSE的JavaFX 2應用程序,我想確保一個特定的代碼被稱爲一個接口的每一個方法:無法攔截切入點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; 
    } 
} 
實現上述接口的類10

下面是AOP的Spring的配置和ControladorDialogoPrincipal bean的實例:

<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

你可以在你的應用程序上下文或者spring配置文件中發佈更多的信息以獲得完整的感覺嗎? –

+0

Hi @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知道通過其上下文控制器(檢查你的春天JavaFX的整合)。最後,如果沒問題,請嘗試使用CGLIB:

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

嗨@zenbeni,有沒有辦法繞過這個限制?在所有需要它的方法中調用travarConexao是非常糟糕的。 – brevleq

+0

@brevleq我不確切地知道你需要什麼,你是否檢查過你的AOP配置是否正確,並且在香草Spring beans上有基本的切入點?嘗試在Spring中定義一個基本的HelloWorldService,並在一個方法上添加一個切入點,然後看看會發生什麼。如果它不起作用,那麼javafx不是問題,可能是依賴/配置問題(有或沒有cglib)。 – zenbeni