application.properties содержат данную информацию:
book.name1 = War and Piece
book.author1 = Leo Tolstoy
book.name2 = Crime and Punishment
book.author2 = Dostoevsky
book.name3 = To Kill a Mockingbird
book.author3 = Harper Lee
И Book.java, который принимает значения из файла.
public class Book {
String name;
String author;
static int bookid = 0;
public Book(){bookid++;}
@Value ("${book.name.concat(bookid)}")
public void setName(String name)
{this.name = name;}
@Value ("${book.author.concat(bookid)}")
public void setAuthor(String name)
{this.author = author;}
public String getBook()
{return name + " by " + author;}
}
И, наконец, класс, содержащий массив книг.
public class UniversityLibrary implements Library{
List<Book> books;
public UniversityLibrary(ArrayList<Book> books) //books are injected by ConfigClass
{
this.books = new ArrayList<>();
for (Book bok: books)
{this.books.add(bok);}
}
}
Результат System.out.println(ubilibrary.getBook(1)) — ${book.name.concat(bookid)} от ${book.author.concat(bookid)} — как и ожидалось, но не удовлетворяет задаче . Создание единой Книги также не помогло бы ситуации.
Нигде не найден правильный синтаксис, чтобы это работало. Я ожидаю, что выражение в Value возьмет значение из bookid и соединит его с ${book.name..}, чтобы получить результат @Value("${book.name1}") и т. д.
Ваша книга выглядит как классическая Сущность.
вы понимаете, что использование идентификатора static
приведет к тому, что он будет иметь одинаковое значение во ВСЕХ книгах
это возможно с @ConfigurationProperties
При условии, что у вас есть следующие свойства:
books[0].name = War and Piece
books[0].author = Leo Tolstoy
books[1].name = Crime and Punishment
books[1].author = Dostoevsky
books[2].name = To Kill a Mockingbird
books[2].author = Harper Lee
вы можете автоматически связать эти свойства с List<Book>
:
@ConfigurationProperties
@Component // we either have to define it as component or specifically instruct Spring to scan for this with `@ConfigurationPropertiesScan`
public class BookProperties {
private List<Book> books;
// IMPORTANT! without a setter, spring won't bind the values
public void setBooks(List<Book> books) {
this.books = books;
}
// getter
}
После этого вы можете автоматически подключиться BookProperties
куда угодно и получить доступ к списку книг (books
).
Для получения дополнительной информации см. соответствующую документацию.
Что касается bookid
, вам также следует определить его в свойствах или добавить логику в установщик, НО этого не может быть static
, иначе он будет иметь одно и то же значение для ВСЕХ объектов книги (потому что именно так работает static
, это свойство уровня класса, а НЕ экземпляр уровень)
bookid — не совсем подходящее имя для этого статического поля. Оно должно было увеличиваться каждый раз при добавлении новой книги (total_books). Спасибо за ваш вклад! попробую с этим поработать
Итак, следуя совету Дж. Аскарова, я получил следующие свойства:
list.books[0].name = War and Piece
list.books[0].author = Leo Tolstoy ...
Оказывается, этот синаксис имеет решающее значение для @ConfigurationProperties. Далее идет класс Book, значения @Value не используются! (Что было для меня новым)
public class Book {
String name;
String author;
public void setName(String name)
{this.name = name;}
public void setAuthor(String author)
{this.author = author;}
public String getBook()
{return name + " by " + author;}
}
BookProperties или UniLibrary в моем случае следуют этому шаблону:
@ConfigurationProperties("list") // and this is why list.* in properties is important!!
public class UniversityLibrary implements Library{
List<Book> books;
//setter goes here
//...
}
И последнее, но не менее важное: ConfigClass. За исключением @EnableAspectJAutoProxy (proxyTargetClass=true), убедитесь, что они у вас есть все.
@Configuration
@ComponentScan("koroler.spring.AOP")
@PropertySource("classpath:application.properties")
@ConfigurationPropertiesScan
@EnableAspectJAutoProxy (proxyTargetClass=true)
public class ConfigClass {
@Bean
@Scope ("prototype")
public Book books()
{
return new Book();
}
@Bean
public UniversityLibrary uniLibrary()
{
return new UniversityLibrary();
}
}
В результате ulibrary.getBook(1) возвращает «Преступление и наказание Достоевского», как и ожидалось. Большое спасибо! Я также надеюсь, что этот ответ поможет кому-то, если вы немного застряли в других решениях c:
application.properties предназначен не для этого. Первым шагом может быть создание CSV-файла с динамически изменяющимися значениями или, что еще лучше, подключение вашего приложения к базе данных.