Bahar özelliklerine beş tür bildirim uygulanabilir:
Bildirimden önce (Önce): hedef yöntem çağrılmadan önce çağrı bildirimi
Bildirimden sonra (Sonra): hedef yöntem tamamlandıktan sonra çağrı bildirimi (normal veya anormal çıkıştan bağımsız olarak)
Döndükten sonra: Hedef yöntem başarıyla yürütüldükten sonra bildirimi çağırın
İstisna bildirimi (Atma sonrası): hedef yöntem bir istisna attıktan sonra çağrı bildirimi
Çevresinde bildirim (Çevresinde): Bildirim, bildirilen yöntemi sarar ve bildirilen yöntem çağrılmadan önce ve sonra özel davranışlar gerçekleştirir.
Yürütme emri:
Sonraki temel uygulamalar Surround bildirim , Önceden haber , Bildirim gönder , İade bildirimi , İstisna bildirimi Uygulamayı gerçekleştirin ve yürütme sırasını gösterin.
Beyanname bildirimi
Yukarıdaki yürütme sırasını doğrulamak için aşağıdaki kodu kopyalayabilirsiniz.
@Görünüş
public class Test {
private static int adım = 0;
@Pointcut ("@ annotation (com.chenyanwu.erp.erpframework.annotation.Log)") // nokta kesim ifadesi
özel void işlemi () {}
@Before ("işlem ()")
public void doBeforeTask () {
System.out.println (++ adım + "Ön bildirim");
}
@After ("işlem ()")
public void doAfterTask () {
System.out.println (++ adım + "bildirim sonrası");
}
@AfterReturning (pointcut = "işlem ()", dönen = "retVal")
public void doAfterReturnningTask (Object retVal) {
System.out.println (++ adım + "dönüş bildirimi, dönüş değeri:" + retVal.toString ());
}
@AfterThrowing (pointcut = "operation ()", throwing = "ex")
public void doAfterThrowingTask (Exception ex) {
System.out.println (++ step + "İstisna bildirimi, istisna bilgisi:" + ex.getMessage ());
}
/ **
* Surround bildirimlerinin ProceedingJoinPoint türü parametreleri taşıması gerekir
* Çevreleyen bildirim, dinamik aracının tüm sürecine benzer ProceedingJoinPoint türü parametreleri, hedef yöntemin çalıştırılıp çalıştırılmayacağını belirleyebilir
* Ve çevreleyen bildirim bir dönüş değerine sahip olmalıdır, dönüş değeri hedef yöntemin dönüş değeridir
* /
// @ Etrafında ("işlem ()")
public Object doAroundTask (ProceedingJoinPoint pjp) {
Dize yöntemadı = pjp.getSignature (). GetName ();
Nesne sonucu = boş;
Deneyin {
// Ön bildirim
System.out.println ("hedef yöntem" + yöntem adı + "start, parametre" + Arrays.asList (pjp.getArgs ()));
// hedef yöntemi çalıştır
sonuç = pjp.proceed ();
// bildirim döndür
System.out.println ("hedef yöntem" + yöntem adı + "başarıyla yürütülür," + sonuç döndürülür);
} catch (Throwable e) {
// İstisna bildirimi
System.out.println ("hedef yöntem" + yöntem adı + "istisna atar:" + e.getMessage ());
}
// Bildirim gönder
System.out.println ("Hedef Yöntem" + yöntem adı + "Son");
dönüş sonucu;
}
}
Dikkat edilmesi gereken bir nokta, giriş noktasıdır: @ Pointcutın ifadesi
biçim:
yürütme (değiştiriciler-model? ret-tip-model bildiren-tip-model? isim-model (param-model) atar-model?)
Parantez içindeki her desen şu anlama gelir:
Misal:
1) yürütme (* ())
// Tüm yöntemlerle eşleşme anlamına gelir
2) yürütme (genel * com. Savage.service.UserService. ())
// com.savage.server.UserService içindeki tüm genel yöntemlerin eşleştiğini gösterir
3) yürütme (* com.savage.server. ())
// com.savage.server paketi ve alt paketleri altındaki tüm yöntemlerin eşleştiğini gösterir
Yukarıdaki temel uygulamanın anlaşılmasıyla, şimdi kodu doğrudan yapıştırıyoruz:
1. Bağımlı kavanoz paketi
org.springframework.boot
Spring-boot-starter-aop
2. Özel ek açıklamalar
@Target (ElementType.METHOD)
@Retention (RetentionPolicy.RUNTIME)
public @interface Günlüğü {
Dize değeri () varsayılan "";
}
3. Yönün farkına varın
@Görünüş
@Sipariş (5)
@Bileşen
public class LogAspect {
private Logger logger = LoggerFactory.getLogger (LogAspect.class);
@Autowired
özel ErpLogService logService;
@Autowired
ObjectMapper objectMapper;
özel ThreadLocal startTime = new ThreadLocal ();
@Pointcut ("@ annotation (com.chenyanwu.erp.erpframework.annotation.Log)")
public void pointcut () {
}
/ **
* Ön bildirim, Kontrolör katmanı işleminden önce müdahale edin
*
* @param joinPoint giriş noktası
* /
@Before ("pointcut ()")
public void doBefore (JoinPoint joinPoint) {
// Geçerli çağrı zamanını alın
startTime.set (yeni Tarih ());
}
/ **
* Normal getiri
*
* @param joinPoint giriş noktası
* @param rvt normal sonucu
* /
@AfterReturning (pointcut = "pointcut ()", dönen = "rvt")
public void doAfter (JoinPoint joinPoint, Object rvt) Exception {atar {
handleLog (joinPoint, null, rvt);
}
/ **
* Anormal bilgi yakalama
*
* @param joinPoint
* @param e
* /
@AfterThrowing (pointcut = "pointcut ()", throwing = "e")
public void doAfter (JoinPoint joinPoint, Exception e) Exception {atar {
handleLog (joinPoint, e, null);
}
@Async
private void handleLog (son JoinPoint birleştirme Noktası, nihai İstisna e, Nesne rvt) İstisna {
// yorum al
Yöntem yöntem = getMethod (joinPoint);
Günlük günlüğü = getAnnotationLog (yöntem);
eğer (log == null) {
dönüş;
}
Şimdiki tarih = yeni Tarih ();
// İşlem veritabanı günlük tablosu
ErpLog erpLog = yeni ErpLog ();
erpLog.setErrorCode (0);
erpLog.setIsDeleted (0);
// Bilgi isteme
HttpServletRequest isteği = ToolUtil.getRequest ();
erpLog.setType (ToolUtil.isAjaxRequest (istek)? "Ajax isteği": "Normal istek");
erpLog.setTitle (log.value ());
erpLog.setHost (request.getRemoteHost ());
erpLog.setUri (request.getRequestURI (). toString ());
// erpLog.setHeader (request.getHeader (HttpHeaders.USER_AGENT));
erpLog.setHttpMethod (request.getMethod ());
erpLog.setClassMethod (joinPoint.getSignature (). getDeclaringTypeName () + "." + joinPoint.getSignature (). getName ());
// İstenen yöntem parametresi değeri
Nesne bağımsız değişkenleri = joinPoint.getArgs ();
// İstenen yöntem parametresi adı
LocalVariableTableParameterNameDiscoverer u
= new LocalVariableTableParameterNameDiscoverer ();
String paramNames = u.getParameterNames (yöntem);
eğer (değiştirgeler! = null paramNames! = null) {
StringBuilder parametreleri = new StringBuilder ();
params = handleParams (params, args, Arrays.asList (paramNames));
erpLog.setParams (params.toString ());
}
String retString = JsonUtil.bean2Json (rvt);
erpLog.setResponseValue (retString.length ()> 5000? JsonUtil.bean2Json ("İstek parametresi verileri görüntülenemeyecek kadar uzun"): retString);
eğer (e! = null) {
erpLog.setErrorCode (1);
erpLog.setErrorMessage (e.getMessage ());
}
Tarih stime = startTime.get ();
erpLog.setStartTime (stime);
erpLog.setEndTime (şimdi);
erpLog.setExecuteTime (şimdi.getTime () - stime.getTime ());
erpLog.setUsername (MySysUser.loginName ());
HashMap browserMap = ToolUtil.getOsAndBrowserInfo (istek);
erpLog.setOperatingSystem (browserMap.get ("os"));
erpLog.setBrower (browserMap.get ("tarayıcı"));
erpLog.setId (IdUtil.simpleUUID ());
logService.insertSelective (erpLog);
}
/ **
* Yorum var mı, varsa anla
* /
private Log getAnnotationLog (Yöntem yöntemi) {
eğer (yöntem! = null) {
dönüş method.getAnnotation (Log.class);
}
boş döndür;
}
özel Yöntem getMethod (JoinPoint joinPoint) {
İmza imzası = joinPoint.getSignature ();
MethodSignature methodSignature = (MethodSignature) imza;
Yöntem yöntem = methodSignature.getMethod ();
eğer (yöntem! = null) {
iade yöntemi;
}
boş döndür;
}
private StringBuilder handleParams (StringBuilder parametreleri, Object args, List paramNames) JsonProcessingException {
for (int i = 0; i