Spring bean在运行时更改配置



我需要会话管理器连接SAP服务器。我使用spring bean创建会话管理器。我从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>

更新这一行的BHD值(->configuration = new AnnotationConfiguration("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;
}

我不是SAP技术方面的专家,但是您可能希望创建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如何知道你想要连接到存储库中的哪个服务器?你得亲自告诉斯普林。以上代码就是其中一种。

现在,如果您想让AHD服务器作为回退(如果连接到BHD失败,连接到AHD),您可以创建一个很好的包装器,如

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

相关内容

  • 没有找到相关文章

最新更新