Есть ли альтернативы, кроме как отпустить идею с определением FilePatcher как бина?
@Lazy
.// Обычный класс. Не компонент.
public class FilePatcher {
private final Path directory;
public FilePatcher(Path directory) {
this.directory = directory;
}
public void hello() {
System.out.println(directory);
}
}
@Component
public class CommitManager {
private final FilePatcher filePatcher;
// Spring сгенерирует объект-заглшку. Реальный бин будет запрошен из
// спринг контекста при первом вызове любого метода объекта-заглушки.
public CommitManager(@Lazy FilePatcher filePatcher) {
this.filePatcher = filePatcher;
}
public void callFilePatcher() {
filePatcher.hello();
}
}
@Component
public class RuntimeSetter {
private final ApplicationContext ctx;
private final CommitManager cm;
public RuntimeSetter(ApplicationContext ctx, CommitManager cm) {
this.ctx = ctx;
this.cm = cm;
}
@Scheduled(initialDelay = 500, fixedDelay = Long.MAX_VALUE)
public void set() {
// Спустя 500 мс становится известен path.
// В этот момент создаём бин FilePatcher вручную.
var factory = (BeanDefinitionRegistry) ctx.getAutowireCapableBeanFactory();
var gbd = new GenericBeanDefinition();
gbd.setBeanClass(FilePatcher.class);
var cav = new ConstructorArgumentValues();
cav.addGenericArgumentValue(Path.of("hello_world"));
gbd.setConstructorArgumentValues(cav);
factory.registerBeanDefinition("filePatcher", gbd);
}
@Scheduled(initialDelay = 1000, fixedDelay = Long.MAX_VALUE)
public void run() {
// Спустя 1000 мс вызываем код, который триггерит резолв lazy бина.
cm.callFilePatcher();
}
}
public class CtxInit implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.getEnvironment()
.getPropertySources()
.addLast(new PropertySource<String>("pathPropertyResolver") {
private volatile String path;
{
var t = new Thread(() -> {
try {
// Спустя 500 мс после старта становится
// известен path.
Thread.sleep(500);
path = "hello_world";
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
t.start();
}
@Override
public Object getProperty(String name) {
// Наш проперти называется myLazyPath.
if ("myLazyPath".equals(name)) {
return path;
}
return null;
}
});
}
}
@SpringBootApplication
@EnableScheduling
public class ApplicationMain {
public static void main(String[] args) {
var sa = new SpringApplication(ApplicationMain.class);
sa.addInitializers(new CtxInit());
sa.run(args);
}
}
@Component
public class FilePatcher {
private final Path directory;
public FilePatcher(@Value("${myLazyPath}") Path directory) {
this.directory = directory;
}
public void hello() {
System.out.println(directory);
}
}
@Component
public class CommitManager {
private final FilePatcher filePatcher;
public CommitManager(@Lazy FilePatcher filePatcher) {
this.filePatcher = filePatcher;
}
public void callFilePatcher() {
filePatcher.hello();
}
}
@Component
public class RuntimeRunner {
private final CommitManager cm;
public RuntimeRunner(CommitManager cm) {
this.cm = cm;
}
@Scheduled(initialDelay = 1000, fixedDelay=Long.MAX_VALUE)
public void run() {
// Спустя 1000 мс вызываем код, который триггерит резолв lazy бина.
cm.callFilePatcher();
}
}
неужели есть только один вариант это обрабатывать с поощью try/catch внутри каждого блока что бы избежать Unhandled exceptions?
private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) {
return Mono.fromCallable(() -> clazz.getDeclaredConstructor(Server.class, Channel.class))
.map(constructor -> ex(() -> constructor.newInstance(this.manager.getServer(), channel)))
.flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args))
.onErrorResume(Mono::error);
}
private <T> T ex(Callable<T> code) {
try {
return code.call();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private @NotNull Mono<JsonObject> invoke(Channel channel, Class<?> clazz, Method method, Object... args) {
return Mono.fromCallable(() -> {
var constructor = clazz.getDeclaredConstructor(Server.class, Channel.class);
return constructor.newInstance(this.manager.getServer(), channel);
})
.flatMap(obj -> new GenericData<JsonObject>().invoke(method, obj, args))
.onErrorResume(Mono::error);
}
class loader, JMM, GC
mvn -am -pl модуль package
Node<T> oldTop = top;
top = new Node<T>(item, oldTop);
class Initable2 {
static int staticNonFinal;
public static void main(String[] args) {
System.out.println(staticNonFinal);
}
}
class Initable2 {
static int staticNonFinal;
// Вот этот блок будет добавлен к
// вашему классу во время компиляции.
static {
staticNonFinal = 0;
}
public static void main(String[] args) {
System.out.println(staticNonFinal);
}
}
class Initable2 {
static int staticNonFinal = 42;
static String a = "hello";
static Cache<String, Integer> b = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
}
class Initable2 {
static int staticNonFinal;
static String a;
static Cache<String, Integer> b;
static {
staticNonFinal = 42;
a = "hello";
b = CacheBuilder.newBuilder()
.maximumSize(100)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build();
}
}
class Initable2 {
static int staticNonFinal = 42;
static Map<Integer, String> statusCodes = new HashMap<>();
static {
statusCodes.put(200, "OK");
statusCodes.put(404, "Not Found");
statusCodes.put(418, "I'm a teapot");
}
}
class Initable2 {
static int staticNonFinal;
static Map<Integer, String> statusCodes;
static {
staticNonFinal = 42;
statusCodes = new HashMap<>()
statusCodes.put(200, "OK");
statusCodes.put(404, "Not Found");
statusCodes.put(418, "I'm a teapot");
}
}
А если в блоке try либо catch выполнить System.exit() ?
В каких случаях следует идти через Collection, а в каких через Iterator? (особенно если надо просто пробежаться всем элементам).
Решение с Iterator выглядит привлекательно при написании класса, в котором реализация интерфейса Collection затруднена или непрактична.
<repository>
<id>upstream</id>
<url>https://ci.nametagedit.com/plugin/repository/everything/com/nametagedit/nametagedit/</url>
</repository>
<repository>
<id>upstream</id>
<url>https://ci.nametagedit.com/plugin/repository/everything/</url>
</repository>
Просто я думал, зачем же нужен в enum valueOf(). Разобрался. Предположил, что метод хранит в себе строковое представление констант, а затем сравнивает вводные данные с ними.
public enum Hello {
FIZZ, BUZZ;
// Данный метод автоматически генерируется компилятором.
// Для любого enum'а.
public static Hello valueOf(String name) {
return Enum.valueOf(Hello.class, name);
}
}
Но так как я знаю, что константы в enum это анонимные классы
Получается мне действительно прийдется перекрывать эти переменные повторным объявлением для разрыва связи с предком?
try (ResultSet rs = statement.executeQuery(query)) {
while (rs.next()) {
System.out.println("User: " + rs.getString("login"));
}
rs.beforeFirst(); // <-- перематываем
while (rs.next()) {
System.out.println("Hello, " + rs.getString("login"));
}
}
class User {
private final String login;
private final String name;
private final String email;
public User(ResultSet rs) throws SQLException {
login = rs.getString("login");
name = rs.getString("name");
email = rs.getString("email");
}
public String getLogin() {
return login;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
}
List<User> users = new ArrayList<>();
try (ResultSet rs = statement.executeQuery(query)) {
while (rs.next()) {
users.add(new User(rs));
}
}
for (User u : users) {
System.out.println("Hello, " + u.getLogin());
}
exec.shutdown();
exec.awaitTermination(100, TimeUnit.SECONDS);