Почему код в блоке stati c выполняется несколько раз? - PullRequest
2 голосов
/ 20 апреля 2020

Я создал класс в Spring при загрузке, чтобы установить sh глобальный объект javers, который может использоваться всеми классами. Это мой код.

@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 () вызывается так много раз? Это какая-то повторная попытка?

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Это происходит столько раз, сколько загружается анонимный класс ConnectionProvider. Следующий код поможет вам лучше понять его:

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
1 голос
/ 20 апреля 2020

Хотя ConnectionProvider создается внутри блока stati c, его переопределенный метод не является ни static (не может быть), ни связан с самим блоком stati c, а с экземпляром connectionProvider.

По сути, вы реализуете метод анонимного класса. Я предполагаю, что ConnectionProvider является интерфейсом, тогда определение класса, реализующего тот же интерфейс, будет фактически таким же, как ваш код:

static
{
    ConnectionProvider connectionProvider = new MyConnectionProvider();
}

Внутренние элементы метода getConnection не привязаны к stati c block, сам экземпляр connectionProvider. Существует несколько вызовов, поскольку метод был вызван несколько раз из экземпляра, определенного в блоке stati c.

...