2016-09-28 62 views
0

在弹簧启动应用程序中,我使用serialPuntit librairie读取串行端口。应用程序中的任何地方访问对象

线程通过onApplicationEvent启动。

工作正常。

@Component 
public class ScanRead implements Runnable { 

    Thread thrd; 
    boolean suspended; 
    boolean stopped; 

    String port = "/dev/ttyUSB0"; 

    final protected static char[] hexArray = "ABCDEF".toCharArray(); 

    public static String bytesToHex(byte[] bytes) { 
     char[] hexChars = new char[bytes.length * 2]; 
     for (int j = 0; j < bytes.length; j++) { 
      int v = bytes[j] & 0xFF; 
      hexChars[j * 2] = hexArray[v >>> 4]; 
      hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
     } 
     return new String(hexChars); 
    } 

    @Override 
    public void run() { 

     try { 

      while (true) { 

       StringBuilder sb = new StringBuilder(); 
       SerialComManager scm = new SerialComManager(); 
       long handle = scm.openComPort(port, true, false, true); 
       byte[] dataRead = {}; 

       scm.configureComPortData(handle, DATABITS.DB_8, STOPBITS.SB_1, PARITY.P_NONE, BAUDRATE.B9600, 0); 
       scm.configureComPortControl(handle, FLOWCONTROL.NONE, 'x', 'x', false, false); 

       long context = scm.createBlockingIOContext(); 

       for (int x = 0; x < 8; x++) { 
        dataRead = scm.readBytesBlocking(handle, 1, context); 
        if (dataRead != null) { 
         sb.append(bytesToHex(dataRead)); 
        } 
       } 

       System.out.println(sb.toString()); 

       scm.unblockBlockingIOOperation(context); 
       scm.destroyBlockingIOContext(context); 
       scm.closeComPort(handle); 

       Thread.sleep(50); 

       synchronized (this) { 
        while (suspended) { 
         wait(); 
        } 
        if (stopped) { 
         break; 
        } 
       } 

      } 
     } catch (InterruptedException exc) { 
      System.out.println(thrd.getName() + " interrupted."); 
     } catch (IOException ex) { 
      Logger.getLogger(ScanRead.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    synchronized void stop() { 
     stopped = true; 
     suspended = false; 
     notify(); 
    } 

    synchronized void suspend() { 
     suspended = true; 
    } 

    synchronized void resume() { 
     suspended = false; 
     notify(); 
    } 

} 


@Component 
public class ScanApplicationStartup implements ApplicationListener<ApplicationReadyEvent> { 
    @Override 
    public void onApplicationEvent(final ApplicationReadyEvent event) { 

    ScanRead sc = new ScanRead(); 

    sc.run(); 
    } 

} 

唯一的缺点,不能使用其他SerialComManager在另一个地方的应用程序在同一端口上阅读。

我搜索一种方法来初始化SerialComManager并在应用程序中的任何地方使用它。

任何建议。

+1

创建一个bean添加getter方法并返回这个对象,bean默认情况下是prototype(每次都返回相同的实例),你可以在你的spring项目的任何地方使用它。 – amitmah

回答

0

您的应用程序的配置类中定义一个bean:

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 

@Configuration 
public class AppConfig { 

    @Bean 
    public SerialComManager getSerialComManager() { 
     return new SerialComManager(); 
    } 
} 

之后,你就可以Autowire实例为需要的类:

import org.springframework.beans.factory.annotation.Autowired; 

@Component 
public class ScanRead { 
    @Autowired 
    private SerialComManager scm; 

    @Override 
    public void run() { 
     // ... 
     long handle = scm.openComPort(port, true, false, true); 
     // ... 
    } 
} 

注意,奇怪的事情开始,如果你发生混合自动装配与静态上下文,所以我会避免,如果可以的话。

+0

不知道是否可以在getSerialComManager中执行更多操作,例如将默认值设置为openComPort。 –

+0

@roberttrudel当然。这种方法没有什么特别之处,它只是普通的Java代码;你可以在那里做任何你会在别处做的事情。 @ Bean所做的唯一事情就是告诉Spring将该方法的结果添加到Spring上下文中。这样,每次你要求一个这种类型的bean时,你都会得到同样的实例。 – nbrooks

+0

好吧,实际上,不能在那里做openport,因为需要处理其他方法的值...所以我认为在做其他的阅读之前,在暂停的方法中,我需要关闭并在简历中打开它。将需要把脉络和处理价值全球化。如何访问ScanRead以便能够在我的控制器中挂起和恢复线程?需要相同的实例,然后在onApplicationEvent中...可能需要改变它。 –

相关问题