0

Ich habe eine Springboot-Anwendung mit einer eigenen Datenquelle (nennen wir DB1) auf Eigenschaften eingestellt funktioniert gut.So erstellen Sie eine dynamische Datenquelle mit SpringBoot

Aber diese Anwendung muss eine neue Datenquelle (DB2) konfigurieren, mit einigen Parametern, die der Benutzer zuvor informiert und in DB1 gespeichert hat.

Meine Idee ist, eine benannte Bean zu erstellen, so dass ein bestimmter Teil meiner Anwendung auf DB2-Tabellen zugreifen kann. Ich denke, es ist möglich, dies zu tun, indem Sie die Anwendung neu starten, aber ich möchte es vermeiden.

Außerdem brauche ich, dass ein Teil meines Codes die neue Datenquelle verwenden (Federdaten jpa, Mappings, usw.). Ich weiß nicht, ob das eine Sache ist, aber es ist eine Webanwendung, daher kann ich die Datenquelle nicht nur für den Anfragethread erstellen.

Können Sie mir helfen?

Vielen Dank im Voraus.

+0

Ich habe eine Lösung gefunden, die den ersten 'EntityManager' injiziert, um die Verbindungsparameter zu erhalten und eine' @ PostConstruct' Annotation zu verwenden, um die zweite Datenquelle zu erstellen. Das einzige Problem bei diesem Ansatz ist, dass ich die Anwendung neu starten muss, wenn die Parameter nicht korrekt sind. –

Antwort

1

Der Frühling hat dynamisches Datenquellen-Routing, wenn Sie dorthin geleitet werden. In meinem Fall ist es das gleiche Schema (WR/RO)

public class RoutingDataSource extends AbstractRoutingDataSource { 

    @Autowired 
    private DataSourceConfig dataSourceConfig; 

    @Override 
    protected Object determineCurrentLookupKey() { 
    return DbContextHolder.getDbType(); 
    } 

    public enum DbType { 
    MASTER, WRITE, READONLY, 
    } 

Dann benötigen Sie eine benutzerdefinierte Anmerkung und einen Aspekt

@Target({ElementType.METHOD, ElementType.TYPE}) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface ReadOnlyConnection { 
} 

@Aspect 
@Component 
@Order(1) 
public class ReadOnlyConnectionInterceptor { 

    Pointcut(value = "execution(public * *(..))") 
    public void anyPublicMethod() {} 

    @Around("@annotation(readOnlyConnection)") 
    public Object proceed(ProceedingJoinPoint proceedingJoinPoint, ReadOnlyConnection readOnlyConnection) throws Throwable   { 
    Object result = null; 
    try { 
     DbContextHolder.setDbType(DbType.READONLY); 
     result = proceedingJoinPoint.proceed(); 
     DbContextHolder.clearDbType(); 
     return result; 
    } finally { 
     DbContextHolder.clearDbType(); 
    } 
    } 
} 

Und dann können Sie wirken auf Sie mit dem Tag @ReadOnlyConnection DB

@Override 
@Transactional(readOnly = true) 
@ReadOnlyConnection 
public UnitDTO getUnitById(Long id) { 
    return unitRepository.findOne(id); 
} 

Ein Beispiel finden Sie hier: https://github.com/afedulov/routing-data-source.

Ich habe das als Grundlage für meine Arbeit verwendet, obwohl es noch läuft, weil ich noch Laufzeitabhängigkeiten auflösen muss (d. H. Hibernate Sharding).

+0

Bitte geben Sie keine Link-Only-Antworten, Links können kaputt gehen und die Antwort wird irrelevant. Setzen Sie die wichtigsten Bits direkt in Ihren Beitrag. – YakovL

+0

Einverstanden. Beispielverhalten mit vollständiger Quellverknüpfung hinzugefügt – Oberst

Verwandte Themen