为什么静态块中的代码会执行多次?

Why does code in static block execute multiple times?

我在 Spring 引导中创建了一个 class 来建立一个全局的 javers 对象,所有 classes 都可以使用。这是我的代码。

@Component
public class JaversInstance {

    public static final Javers javers;
    static
    {

        ConnectionProvider connectionProvider = new ConnectionProvider() {
            @Override
            public Connection getConnection() throws SQLException {
                String url = "any_url";
                Properties props = new Properties();
                props.setProperty("user", "test");
                props.setProperty("password", "test");
                DriverManager.getConnection(url, props);
                System.out.println("CONNECTION PROVIDER invoked");
                return DriverManager.getConnection(url, props);
            }
        };

        JaversSqlRepository sqlRepository = SqlRepositoryBuilder
                .sqlRepository()
                .withConnectionProvider(connectionProvider)
                .withDialect(DialectName.MYSQL).build();
        System.out.println("JAVERS instance creation");
        javers = JaversBuilder.javers().registerJaversRepository(sqlRepository).build();
    }

    private JaversInstance() {

    }

}

输出:

JAVERS instance creation
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked
CONNECTION PROVIDER invoked

谁能告诉我这里发生了什么。为什么 getConnection() 被调用了这么多次?这是重试吗?

虽然 ConnectionProvider 是在静态块中实例化的,但它的重写方法既不 static (不可能)也不与静态块本身相关,而是与实例相关 connectionProvider.

基本上,你实现了一个匿名的方法class。我想 ConnectionProvider 是一个接口,然后定义一个 class 实现完全相同的接口实际上与您的代码相同:

static
{
    ConnectionProvider connectionProvider = new MyConnectionProvider();
}

getConnection 方法的内部未绑定到静态块,实例 connectionProvider 本身是。由于已从静态块中定义的实例多次调用该方法,因此存在多次调用。

它发生的次数与加载 ConnectionProvider 的匿名 class 的次数一样多。以下代码将帮助您更好地理解它:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Main {
    static Comparator<Integer> comparator;
    static {
        comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                System.out.println("Hello");
                return 0;
            }
        };
    }

    public static void main(String[] args) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(40);
        list.add(20);
        list.add(10);
        list.add(30);
        Collections.sort(list, comparator);
    }
}

输出:

Hello
Hello
Hello