Я реализовал АОП для ведения журнала.
LoggingAspect
@Aspect
public class LoggingAspect {
private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(LoggingAspect.class);
@Before("execution(public * *(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("logBefore() is running!");
System.out.println("classname : " + joinPoint.getClass().getCanonicalName() + "," + joinPoint.getSignature().getName());
System.out.println("******");
}
}
и следующую конфигурацию в app-ctx.xml
<beans xmlns = "http://www.springframework.org/schema/beans"
xmlns:context = "http://www.springframework.org/schema/context"
xmlns:xsi = "http://www.w3.org/2001/XMLSchema-instance"
xmlns:p = "http://www.springframework.org/schema/p"
xmlns:aop = "http://www.springframework.org/schema/aop"
xmlns:tx = "http://www.springframework.org/schema/tx"
xsi:schemaLocation = "
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<context:component-scan
base-package = "com.pms" />
<aop:aspectj-autoproxy />
<bean id = "loggingAspect"
class = "com.pms.advice.LoggingAspect" />
</beans>
но он выводит для всех классов, которые я получаю
logBefore() is running!
classname : org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint,getConnection
******
пожалуйста посоветуй





Я никогда не пойму, почему так много разработчиков вызывают методы на JoinPoint для извлечения конкретной информации, которую они получают бесплатно, просто регистрируя сам экземпляр точки соединения. Здесь есть все: тип точки соединения, сигнатура метода с именем класса и тип возврата. Это то, что вам нужно, если вы действительно хотите знать, что происходит в ваших аспектах. Скрытие информации путем регистрации ее части значительно усложняет отладку. Кроме того, вызов большого количества методов не ускоряет процесс ведения журнала. А потом они жалуются, что АОП "медленный". ;-)
Как бы то ни было, вы хотите использовать здесь joinPoint.getSignature().getDeclaringTypeName(). Вместо этого вы регистрируете класс точки соединения и имя перехваченного метода.
Внимание, joinPoint.getSignature().getDeclaringType() предоставит вам тип динамического прокси, который, вероятно, не тот, который вам нужен.
Обновлять: Если вы используете ((MethodSignature) thisJoinPoint.getSignature()).get*(), у вас есть доступ к еще парочке геттеров:
Method getMethod()
Class getReturnType()
Class[] getParameterTypes()
Class[] getExceptionTypes()
String[] getParameterNames()
String toString()
int getModifiers()
String getName()
String toShortString()
String toLongString()
Class getDeclaringType()
String getDeclaringTypeName()
И, что довольно интересно, в этом случае ((MethodSignature) thisJoinPoint.getSignature()).getDeclaringType() дает вам настоящий класс, а не прокси-класс.
Конечно, ваш вопрос заключался в том, почему было напечатано неправильное имя класса. Я показал вам, как напечатать правильное имя класса. Так в чем проблема? Если вам нужно имя метода, просто распечатайте его, как будто вы уже знаете, как это сделать - см. Свой собственный пример кода. Теперь, если нет ничего другого, я был бы признателен, если бы вы приняли и проголосовали за мой ответ.
проблема в том, что я получаю тот же результат, где я должен получить соответствующее имя класса и метода. Похоже, я чего-то не понимаю или делаю что-то не так Я указал свой код выше
Комментарий не подходит для кода публикации. Пожалуйста, отредактируйте свой вопрос, добавив новый код внизу. И, кстати, я согласен, что вы, должно быть, делаете что-то не так. Однако без понимания вашего кода я не могу сказать что именно. Протестировал свой код, работает. Самый простой способ воспроизвести вашу проблему - опубликовать полный образец проекта на GitHub, чтобы я мог его клонировать и запустить.
Я могу опоздать на вечеринку, но это может кому-то помочь.
Я считаю, что @Aaruhi хочет, чтобы его реализованные классы регистрировались. Если да, то это поможет:
@Before("execution(* <your_pakage_name>..*.*(..))")
public void logBefore(JoinPoint joinPoint) {
System.out.println("logBefore() is running!");
System.out.println("classname : " + joinPoint.getSignature().getDeclaringTypeName() + "," + joinPoint.getSignature().getName());
System.out.println("******");
}
Это распечатает журналы для всех частных, общедоступных и внутренних методов. Обновите <your_pakage_name>, это позволит вести журнал для всех классов, подпадающих под данный <your_pakage_name>.
joinPoint.getSignature().getDeclaringTypeName()
- Это напечатает имя вашего реализующего класса.
ПРИМЕЧАНИЕ - Обновите выражение pointcut до execution(public * <your_pakage_name>..*.*(..)), чтобы включить ведение журнала только для общедоступных методов.
Он все еще не работает Я пробовал ((MethodSignature) thisJoinPoint.getSignature ()). GetDeclaringTypeName () i, e, System.out.println ("****** Имя метода:" + ((MethodSignature) joinPoint.getSignature ()). getDeclaringTypeName ()); но я все еще получаю результат ****** Имя метода: javax.sql.DataSource вместо каждого метода. пожалуйста, порекомендуйте