自定義註解(spring)

終於有時間可以在這裏寫一篇博文了,今天寫一下我在項目中用到的自定義註解,就是在每次操作項目的時候,想把它的操作加在我的數據庫中,簡單地說就是日誌管理,這些東西都寫完之後,我就問我自己,問什麼要自定義註解寫,而不是什麼模式(代理模式,裝飾器模式…),原始代碼等等,一下子楞了,於是學習了這個東西,今天就在這裏總結一下。。。
編程思想:垂直化編程,就是A—B---C—D…等執行下去,一個邏輯一個邏輯完了再執行下一個,但是spring 中AOP提供了一種思想,它的作用就是,當在業務不知情的情況下,對業務代碼的功能的增強,這種思想使用的場景,例如事務提交、方法執行之前的權限檢測、日誌打印、方法調用事件等等。
就利用我的日誌管理來述說一下這個AOP思想下的自定義註解是如何來實現的。。。
java在我們要自定義註解的時候提供了它自己的自定義語法以及元註解,元註解(負責註解其他註解): Java5.0定義了4個標準的meta-annotation類型,它們被用來提供對其它 annotation類型作說明。Java5.0定義的元註解:
    1.@Target,
    2.@Retention,
    3.@Documented,
    4.@Inherited
  這些類型和它們所支持的類在java.lang.annotation包中可以找到。
  1.@Target:用戶描述註解的作用範圍
  取值(ElementType)有:
    1.CONSTRUCTOR:用於描述構造器
    2.FIELD:用於描述域
    3.LOCAL_VARIABLE:用於描述局部變量
    4.METHOD:用於描述方法
    5.PACKAGE:用於描述包
    6.PARAMETER:用於描述參數
    7.TYPE:用於描述類、接口(包括註解類型) 或enum聲明
2.@Retention:表示需要在什麼級別保存該註釋信息
取值(RetentionPoicy)有:
    1.SOURCE:在源文件中有效(即源文件保留)
    2.CLASS:在class文件中有效(即class保留)
    3.RUNTIME:在運行時有效(即運行時保留)(常用)
  3.@Documented:Documented是一個標記註解
  4.@Inherited :用於聲明一個註解;
自定義註解語法:
public @interface 註解名 {定義體}

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {

    String value() default "";
}
  

注意:
1.只能用public或默認(default)這兩個訪問權修飾.例如,String value();這裏把方法設爲default默認類型
2.這裏的參數成員可以是八種基本數據類型,和String,Enum,Class,annotations等數據類型,以及這一些類型的數組,這裏是String
3.最好把參數名稱設爲"value()" 後面爲默認的值。

/**
 * 系統日誌,切面處理類
 * 
 * @author stm
 * @email [email protected]
 * @date 2017年11月21日
 */
@Aspect
@Component
public class SysLogAspect {

	@Autowired
	private LogService logService;
	//這個裏面需要寫自定義註解的全限定名(包名+類名)
	@Pointcut("@annotation(com.stm.controller.base.annotation.SysLog)")
	public void logPointCut() { 
		
	}

	@Around("logPointCut()")
	public Object around(ProceedingJoinPoint point) throws Throwable {
		long beginTime = System.currentTimeMillis();
		//執行方法
		Object result = point.proceed();
		//執行時長(毫秒)
		long time = System.currentTimeMillis() - beginTime;
		//保存日誌
		saveSysLog(point, time);
		return result;
	}

	/**
	 * 保存系統日誌
	 * @param joinPoint
	 * @param time
	 */
	private void saveSysLog(ProceedingJoinPoint joinPoint, long time) {

		MethodSignature signature = (MethodSignature) joinPoint.getSignature();
		Method method = signature.getMethod();
		/*SysLog syslog = method.getAnnotation(SysLog.class);
		if(syslog != null){
			//註解上的描述
			System.out.println(syslog.value());
		}*/
		/*SysLog sysLog = new ();*/
//獲取request請求
		ServletRequestAttributes attr = (ServletRequestAttributes) RequestContextHolder.currentRequestAttributes();
		HttpServletRequest request = attr.getRequest();

		UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent"));
		Browser browser = userAgent.getBrowser();
		String browsers = browser+"";
		System.out.println("瀏覽器    "+browsers);
		OperatingSystem os = userAgent.getOperatingSystem();
		String oss = os+"";
		System.out.println("os  "+oss);
		String ip = "";
		try {
			ip = InetAddress.getLocalHost().getHostAddress(); //ip 地址
		} catch (UnknownHostException e) {
			e.printStackTrace();
		}
		System.out.println("ip   "+ip);
		Date date = new Date();
		System.out.println(date);
		com.stm.pojo.system.SysLog  sysLog  =  new com.stm.pojo.system.SysLog();
		SysLog syslog = method.getAnnotation(SysLog.class);
		HttpSession session = request.getSession();
		String userName = (String) session.getAttribute("userName");
		if(syslog != null){
			//註解上的描述
			sysLog.setLogIp(ip);
			sysLog.setLogRemark(syslog.value());
			sysLog.setLogTime(date);
			sysLog.setUserName(userName);
			sysLog.setLogSystem(oss);
			sysLog.setLogBrowser(browsers);
		}
		//請求的方法名
		String className = joinPoint.getTarget().getClass().getName();
		String methodName = signature.getName();
		//sysLog.setMethod(className + "." + methodName + "()");
		logService.insert(sysLog);
	}
}

如何使用?
例如在用戶登錄的時候需要把相關的 信息添加到數據庫中,這個時候就需要在登錄成功之後在跳轉到列表的時候添加註解:

	 @SysLog("用戶登錄")
	 @RequestMapping("/main/index")
	    public String index(){
	        return "main/index";
	    }

而這個註解中寫的(“用戶登錄”)就是添加自定義時候的默認值的value()相對應的值。。。
對了這裏需要配置aop以及依賴

<!-- aop 註解實現 -->  
<aop:aspectj-autoproxy/>  
<!-- AspectJ -->  
<dependency>  
    <groupId>org.aspectj</groupId>  
    <artifactId>aspectjrt</artifactId>  
    <version>1.6.10</version>  
</dependency>  
<dependency>  
    <groupId>org.aspectj</groupId>  
    <artifactId>aspectjweaver</artifactId>  
    <version>1.7.2</version>  
</dependency>  

今天就到這裏,之後會更詳細的整理!!!

發佈了45 篇原創文章 · 獲贊 61 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章