2017-02-14 17 views
0

У меня есть класс с именем PersonDAOImpl, где я использую Hibernate для сохранения данных в моей базе данных.Как написать pointcut для получения операции над методом класса?

Чтобы проверить класс, я создал другой класс, используя аннотацию @Aspect, где я объявил несколько пунктов и советов. Каждый раз, когда я вставляю, обновляю или удаляю человека, я могу хранить на столе правильную информацию о выполненной операции.

Однако теперь у меня больше классов DAO, и я не хочу создавать больше классов аспектов или больше. Советы для каждого метода для каждого DAO. Вместо этого я хочу «захватить» операции persist(), update() или delete() в одном pointcut.

Например, у меня есть этот метод на моем DAO:

@Override 
@Transactional 
public void addPerson(Person p) { 
    Session session = this.sessionFactory.getCurrentSession(); 
    session.persist(p); 
    session.flush(); 
    logger.info("Person saved successfully, Person Details="+p); 
} 

И это, как я аудит вставки:

@Pointcut("execution(* com.dacasals.raspertwo.dao.PersonDAOImpl.addPerson(..))") 
public void addNewPerson() { 
} 

@After("addNewPerson()") 
public void aP() { 
    System.out.println("added a new person"); 
    operation = "Insert"; 
    date = Calendar.getInstance().getTime(); 
    register(operation, date); 
} 

Но я хочу что-то вроде @Pointcut ("исполнение (* ком .dacasals.raspertwo.dao.anydaoclass.anymethod.persist (..)) ")

Я имею в виду pointcut для любого метода на любом из моих классов DAO, где вызывается persist(). То же самое для update() и delete().

Как я могу это достичь? Я пробовал с «внутри» и «внутри кода», но ничего не происходит. Заранее спасибо.

+0

Не использовать АОП для этого, но использовать JPA сущности слушателей для того, те, которые предназначены для этого. –

ответ

0

Вместо выражения исполнения вы можете использовать внутри выражения что-то вроде этого.

within(com.yourpackage..*) 

Для этого вам необходимо убедиться, что все ваши DAO находятся в этом пакете. Вышеприведенное выражение будет соответствовать всем методам, определенным в классах внутри пакета com.yourpackage и подпакетах классов.

Вот краткий документ, если вы хотите, чтобы настроить его другим способом, Pointcut Expressions in Spring

+0

У меня есть все мои классы DAO в том же пакете, теперь, как я могу получить доступ к persist() внутри метода addPerson, используя ваш пример? – Ethan

+0

Это выражение должно перехватывать вызов метода. –

0

Я хотел бы использовать «AroundAdvice».

Цитата документации:

Around advice runs "around" a matched method execution. It has the opportunity to do work both before and after the method executes, and to determine when, how, and even if, the method actually gets to execute at all.

Around Advice Spring documentation

Таким образом, в вашем примере, вы бы метод:

@Around("com.dacasals.raspertwo.dao.*.persist(..)") 
public Object doSomething(ProceedingJoinPoint pjp) throws Throwable { 

} 

Таким образом, каждый раз кто-то на "com.dacasals .raspertwo.dao 'вызовы persist method, Spring Aspect будет вызывать doSomething способ. Вокруг консультаций работает как до, так и после того, как метод выполняется, поэтому вам следует позаботиться о том, чтобы не делать то же самое дважды.

Я бы создал конкретный метод для каждой операции (один для вставки, другой для обновления и удаления), но вы можете использовать тот же метод с использованием операторов короткого замыкания.Таким образом, ваш @Around аннотации будут, как:

@Around("com.dacasals.raspertwo.dao.*.persist(..) || com.dacasals.raspertwo.dao.*.update(..) || com.dacasals.raspertwo.dao.*.delete(..)") 
public Object doSomething(ProceedingJoinPoint pjp) throws Throwable { 

} 
+0

, когда я добавил ваш пример, у меня получилась ошибка: Pointcut is malformed: шаблон шаблона шаблона ошибки недопустим, должен использовать имя типа – Ethan

+0

Я также пробовал: \t @Pointcut ("исполнение (* com.dacasals.raspertwo.dao. * .persist (..)) ") \t общественных недействительный метод() {} \t \t @Around (" метод() ") \t общественных недействительный йоЗотеЬЫпд (ProceedingJoinPoint PJP) бросает Throwable { \t \t pjp.proceed(); \t \t System.out.println («Это работает!»); \t \t operation = "Insertado"; \t \t date = Calendar.getInstance(). GetTime(); \t \t регистр (операция, дата); \t} И это не сработало. Я изменил выражение на @Pointcut («исполнение (* com.dacasals.raspertwo.dao.PersonDAOImpl.addPerson (..))»), и оно сработало! Есть идеи? – Ethan

+1

Бруно, зачем использовать '@ Around', если' @ After' дешевле? Более дорогой тип советов не решает проблему, правый pointcut делает. Этан, неудивительно, что имена методов 'persist' и' update' (просто примеры!) Не соответствуют вашему методу с именем 'addPerson'. Если вы думаете немного перед копированием и вставкой кода, вы можете ответить на него сами. И BTW, чтобы сделать код более стабильным, а также повлиять на подпакеты, я предлагаю вам использовать обозначение '..' следующим образом:' execute (* com.dacasals.raspertwo.dao .. * (..)) 'или просто 'внутри (com.dacasals.raspertwo.dao .. *)' – kriegaex