1

現在、同じスキーマを持つ複数のデータベースを使用するアプリケーションがあります。現時点では、ユーザーのセッションに基づいてそれらを切り替えるカスタム ソリューションを使用しています。これは経由で機能します

public final class DataSourceProxy extends BasicDataSource {

    ...

    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null && auth.getDetails() instanceof Map) {

        Map<String, String> details = (Map<String, String>) auth.getDetails();
        String targetUrl = details.get("database");

        Connection c = super.getConnection();
        Statement  s = c.createStatement();
        s.execute("USE " + targetUrl + ";");
        s.close();
        return c;
    } else {
        return super.getConnection();
    }
}

を使用してソリューションを構築しAbstractRoutingDataSourceます。問題は:

@Component
public class CustomRoutingDataSource extends AbstractRoutingDataSource {
    @Autowired
    Environment env;

    @Autowired
    DbDetailsRepositoy repo;

    public CustomRoutingDataSource() {
        Map<Object, Object> targetDataSources = new HashMap<Object, Object>();
        for(DBDetails dbd : repo.findAll() {
            // create DataSource and put it into the map
        }
        setTargetDataSources(new HashMap<Object, Object>());
    }   

    @Override
    protected Object determineCurrentLookupKey() {
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        if (auth != null && auth.getDetails() instanceof Map) {
            Map<String, String> details = (Map<String, String>) auth.getDetails();
            return details.get("database");
        }
        return null;
    }   
}

コンストラクター内で (または 経由でも@PostConstruct)、targetDataSources Map. しかし (!) これには、独自の DataSource と Entity Manager を持つ別のデータベースに保存されている接続の詳細が必要です。

Spring は Bean 構築の順序を決定できないようです。または、何かが足りないだけかもしれません。リポジトリにアクセスすると、常に a が表示されNullPointerExceptionます(btwは a ですJpaRepository)。

Spring 3.2.3、Spring Data、Hibernate 4.2 を使用しています。Spring および Spring Security の Annotation と Java コードの構成を完了します。

助けてください!

4

1 に答える 1

1

もちろん、Spring はプロパティを設定する前にコンストラクターを呼び出す必要があります。しかし、それはSpringのことではなく、基本的なJava 101であり、フィールドインジェクションを使用することの多くの欠点の1つです.

これを回避するには、依存関係をコンストラクターに追加するだけです。

@Component
class CustomRoutingDataSource extends AbstractRoutingDataSource {

  @Autowired
  public CustomRoutingDataSource(DbDetailsRepository repo, Environment environment) {
    …
  }
  …
}
于 2013-07-10T16:08:28.547 に答える