Аспект применяется к прокси , окружающему компонент. Обратите внимание, что каждый раз, когда вы получаете ссылку на bean-компонент, на самом деле это не класс, на который ссылается ваша конфигурация, а синтетический класс, реализующий соответствующие интерфейсы, делегируя фактический класс и добавляя функциональность, например, ваш AOP.
В приведенном выше примере вы вызываете непосредственно в классе, тогда как если этот экземпляр класса вводится в другой как компонент Spring, он вводится как его прокси-сервер, и, следовательно, вызовы методов будут вызваны на прокси (и аспекты будут активированы)
Если вы хотите достичь вышеизложенного, вы можете разделить method1
/ method2
на отдельные компоненты или использовать структуру AOP, не ориентированную на весы.
Подробное описание Spring doc и несколько обходных решений (включая мое первое предложение выше)
Иногда у вас есть две сущности, и между ними существует связь. Например, у вас может быть сущность под названием University
и другая сущность под названием Student
, и у университета может быть много студентов:
Сущность University может иметь некоторые основные свойства, такие как id, имя, адрес и т.д., а также свойство коллекции под названием students, которое возвращает список студентов для данного университета:
public class University {
private String id;
private String name;
private String address;
private List<Student> students;
// setters and getters
}
Теперь, когда вы загружаете университет из базы данных, JPA загружает для вас его поля id, имя и адрес. Но у вас есть два варианта того, как должны быть загружены студенты:
getStudents()
университета. Когда у университета много студентов, неэффективно загружать всех студентов вместе с ним, особенно когда они не нужны, и в таких случаях вы можете объявить, что хотите, чтобы студенты загружались тогда, когда они действительно нужны. Это называется ленивой загрузкой.
Вот пример, где students
явно помечен для загрузки с нетерпением:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.EAGER)
private List<Student> students;
// etc.
}
А вот пример, где students
явно помечен для ленивой загрузки:
@Entity
public class University {
@Id
private String id;
private String name;
private String address;
@OneToMany(fetch = FetchType.LAZY)
private List<Student> students;
// etc.
}
Из Javadoc:
Стратегия EAGER - это требование к времени выполнения провайдера персистентности, что данные должны быть получены с готовностью. Стратегия LAZY - это подсказка времени выполнения провайдера персистентности, что данные должны быть извлечены лениво при первом обращении к ним.
Например, eager является более проактивным, чем lazy. Лень происходит только при первом использовании (если провайдер принимает подсказку), в то время как при использовании eager данные (могут) быть предварительно извлечены.
В основном,
LAZY = fetch when needed
EAGER = fetch immediately
EAGER
Загрузка коллекций означает, что они полностью загружаются в то время, когда загружается их родитель. Так, если у вас есть Курс
и у него есть Список<Студент>
, все студенты будут извлечены из базы данных в момент извлечения Курса
.
LAZY
, с другой стороны, означает, что содержимое Списка
извлекается только тогда, когда вы пытаетесь получить к нему доступ. Например, при вызове course.getStudents().iterator()
. Вызов любого метода доступа к List
инициирует обращение к базе данных для извлечения элементов. Это реализуется путем создания прокси вокруг List
(или Set
). Так что для ваших ленивых коллекций конкретными типами будут не ArrayList
и HashSet
, а PersistentSet
и PersistentList
(или PersistentBag
)