java Spring bean在运行时更改配置

2admgd59  于 2023-04-04  发布在  Java
关注(0)|答案(1)|浏览(132)

我需要session manager来连接SAP服务器。我使用spring bean来创建session manager。我从hibersap.xml获取SAP服务器配置。我以前连接到单个服务器。但现在我需要连接到两个或更多服务器。为了从hibersap.xml读取必要的配置,我需要在运行时更新spring bean,我该怎么做?
2个独立的会话管理器,名称分别为BHD和AHD。

<session-manager name="BHD">
    <context>org.hibersap.execution.jco.JCoContext</context>
    <properties>
        <property name="jco.client.client" value="111" />
        <property name="jco.client.user" value="AAA" />
        <property name="jco.client.passwd" value="11Q1Q1Q1Q" />
        <property name="jco.client.ashost" value="11.11.11.11" />
        <property name="jco.client.sysnr" value="00" />
    </properties>
    <annotated-classes>
        <annotated-class>com.ldap.connection.sap.bapi.RfcLdapParameters</annotated-class>
        <annotated-class>com.ldap.connection.sap.bapi.RfcSapUserDetails</annotated-class>
        <annotated-class>com.ldap.connection.sap.bapi.UsernameAndMailModel</annotated-class>
    </annotated-classes>
</session-manager>
<session-manager name="AHD">
    <context>org.hibersap.execution.jco.JCoContext</context>
    <properties>
        <property name="jco.client.client" value="222" />
        <property name="jco.client.user" value="BBB" />
        <property name="jco.client.passwd" value="2Q2Q2Q2Q22" />
        <property name="jco.client.ashost" value="22.22.22.22" />
        <property name="jco.client.sysnr" value="00" />
    </properties>
    <annotated-classes>
        <annotated-class>com.ldap.connection.sap.bapi.RfcLdapParameters</annotated-class>
        <annotated-class>com.ldap.connection.sap.bapi.RfcSapUserDetails</annotated-class>
        <annotated-class>com.ldap.connection.sap.bapi.UsernameAndMailModel</annotated-class>
    </annotated-classes>
</session-manager>

将下面这一行(-〉configuration = new AnnotationConfiguration("BHD"))中的BHD值更新为AHD可以解决这个问题。但是我如何在运行时做到这一点呢?

@Configuration
@Slf4j
public class HibersapConfiguration {    

@Bean
public SessionManager sessionManager() {
    String sname = System.getProperty("java.systemname");
    AnnotationConfiguration configuration = null;
    
    if(sname != null) {
        if(BtcConstants.LIVE_SYSTEM_NAME.equals(sname)) {
            log.info("SAP üretim canlı sisteme bağlanılıyor...");
        }
        
        if(BtcConstants.DEV_SYSTEM_NAME.equals(sname)){
            configuration = new AnnotationConfiguration("BHD");
            log.info("SAP üretim dev sisteme bağlanılıyor...");
        }
        
    }else {
        configuration = new AnnotationConfiguration("BHD");
        log.info("Local'den SAP üretim dev sisteme bağlanılıyor...");
    }
    
    
    return configuration.buildSessionManager();
 } }

我注入会话管理器的存储库:

@Slf4j
@Repository
public class SapUserRepository implements SapUserRepositoryI {

private final SessionManager sessionManager;

public SapUserRepository(SessionManager sessionManager) {
    this.sessionManager = sessionManager;
}

@Override
public List<SapUser> findPersonalDetailFromSap(Date currentDate, String pernr) {

    List<SapUser> sapUserList = new ArrayList<SapUser>();
    RfcSapUserDetails details = new RfcSapUserDetails();
    details.setCurrentDate(currentDate);
    details.setPernr(pernr);
    
    Session session = null;
    if(sessionManager != null) {
        log.info("'findPersonalDetailFromSap' için session açıldı");
        session = sessionManager.openSession();
        
        try {
            log.info("Personel verileri çekiliyor...");
            session.execute(details);
            sapUserList = details.getSapUserList();
        } finally {
            session.close();
            log.info("session kapatıldı");
        }
    }else {
        log.error("sessionManager null geldi !");
    }

    return sapUserList;
}
vq8itlhq

vq8itlhq1#

我不是SAP技术方面的Maven,但您可能希望创建2个单独的SessionManager并按名称(@Qualifier)注入它们。

class SAPConfig {
  // return a bean of BHD here
  @Bean("BHDSAPServer")
  SessionManager createBHDServer() { ... } 
  
  // return a bean of AHD here
  @Bean("AHDSAPServer")
  SessionManager createAHDServer() { ... }
}

// this snippet is in SAPUserRepository
public SapUserRepository(
  @Qualifier("BHDSAPServer") SessionManager bhdSessionManager,
  @Qualifier("AHDSAPServer") SessionManager ahdSessionManager) {
    this.bhdSessionManager = bhdSessionManager;
    this.ahdSessionManager = ahdSessionManager;
}

Spring如何知道你想连接到你的仓库中的哪个服务器?你必须自己告诉Spring。上面的代码就是这样的一种方式。
现在,如果您想让AHD服务器作为后备(如果连接到BHD失败,则连接到AHD),您可以创建一个很好的 Package 器,如

@Component
class ChainedSAPServer {
  Map<String, SessionManager> sessionManagers;
  
  // Spring will automatically inject (@Autowired) every
  // SessionManager coercible (can be cast to SessionManager)
  // beans in this constructor. If you happen to not use 
  // classpath scanning (@ComponentScan), Spring will also
  // 
  ChainedSAPServer(List<SessionManager> sessionManagers) {
    this.sessionManagers = sessionManagers
       .stream()
       .collect(Collectors.toMap(sm -> sm.getName(), Function.identity());
  }

  Session openSession() {
    // check each session manager one by one, if one fails go to next
  }

  // You can also smartly decide which SessionManager is
  // responsible for what usage. You can simply inject only
  // this wrapper to your repositories.
  Session openSessionWith(String sessionManagerName) {
    return sessionManagers.get(sessionManagerName).openSession();
  }
}

相关问题