终于有时间可以在这里写一篇博文了,今天写一下我在项目中用到的自定义注解,就是在每次操作项目的时候,想把它的操作加在我的数据库中,简单地说就是日志管理,这些东西都写完之后,我就问我自己,问什么要自定义注解写,而不是什么模式(代理模式,装饰器模式…),原始代码等等,一下子楞了,于是学习了这个东西,今天就在这里总结一下。。。

编程思想:垂直化编程,就是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 comstm@163.com
* @date 2017年11月21日
*/
@Aspect
@Component
public class SysLogAspect { @Autowired
private LogService logService;
//这个里面需要写自定义注解的全限定名(包名+类名)
@Pointcut("@annotation(com.bw.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.bw.pojo.system.SysLog sysLog = new com.bw.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>

今天就到这里,之后会更详细的整理!!!

自定义注解(spring)的更多相关文章

  1. Java自定义注解的使用

    什么是注解? #============================================================================================ ...

  2. 使用spring aspect控制自定义注解

    自定义注解:这里是一个处理异常的注解,当调用方法发生异常时,返回异常信息 /** * ErrorCode: * * @author yangzhenlong * @since 2016/7/21 */ ...

  3. spring - 自定义注解

    本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetTy ...

  4. 利用Spring AOP自定义注解解决日志和签名校验

    转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...

  5. Spring 自定义注解,配置简单日志注解

    java在jdk1.5中引入了注解,spring框架也正好把java注解发挥得淋漓尽致. 下面会讲解Spring中自定义注解的简单流程,其中会涉及到spring框架中的AOP(面向切面编程)相关概念. ...

  6. spring AOP 和自定义注解进行身份验证

    一个SSH的项目(springmvc+hibernate),需要提供接口给app使用.首先考虑的就是权限问题,app要遵循极简模式,部分内容无需验证,用过滤器不能解决某些无需验证的方法 所以最终选择用 ...

  7. 照虎画猫写自己的Spring——自定义注解

    Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean 基于XML配置的依赖注入 所以,理所当然,今天该实现基于注解的依赖注入了. 基于XML配 ...

  8. 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  9. spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,guava限流,定时任务案例, 发邮件

    本文介绍spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,定时任务案例 集成swagger--对于做前后端分离的项目,后端只需要提供接口访问,swagger提供了接口 ...

  10. 使用Spring Aop自定义注解实现自动记录日志

    百度加自己琢磨,以下亲测有效,所以写下来记录,也方便自己回顾浏览加深印象之类,有什么问题可以评论一起解决,不完整之处也请大佬指正,一起进步哈哈(1)首先配置文件: <!-- 声明自动为sprin ...

随机推荐

  1. php 类名和方法名相同(构造函数)

    //php 5.6class father{ public function __construct() { echo __METHOD__; }} class son extends father{ ...

  2. node.js 生成二维码

    因为自己的项目中,想在商品详情页上 显示一个 商品优惠券的二维码. 以此为需求. node.js 后台代码 const qr_image = require("qr-image") ...

  3. JRebel springboot部署idea

    JRebel springboot部署idea     http://127.0.0.1:8888/88414687-3b91-4286-89ba-2dc813b107ce   ctrl+shift+ ...

  4. 小程序一个大盒子里面的盒子内容居中对其显示wxss写法

    对小程序研究感兴趣的可加(交流QQ群:604788754)入群联系群主可得到小程序教学资源. 这个案例只是想展示效果,内容部分未进行for循环绑定处理: WXML: <view class=&q ...

  5. A、B两个线程交替打印1 -- 100

    方案一:import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.u ...

  6. WPF拖动总结

    https://www.cnblogs.com/DebugLZQ/archive/2013/05/07/3062733.html <Window xmlns="http://schem ...

  7. Oralce数据库的优化

    Oralce数据库的优化(面试必问) (1) 选择最有效率的表名顺序(只在基于规则的优化器中有效):ORACLE 的解析器按照从右到左的顺序处理FROM子句中的表名,FROM子句中写在最后的表(基础表 ...

  8. 用jackson包实现json、对象、Map之间的转换

    jackson API的使用 用jackson包实现json.对象.Map之间的转换

  9. python 进程池Pool的apply_async方法以及一些需要注意的地方

    在写多进程的时候我发现一个问题,用Pool的apply_async(异步非阻塞)的时候传入实例函数会出错,或者说是子进程被跳过似的感觉(python2.7). 但是用python3.7的话没有任何问题 ...

  10. java基础3(二)

    基础加强 类加载器 A.类加载器获取classpath下任意内容 注意: 可以通过ClassLoader可以获取classpath下的所有内容. SpringMVC 1.整体架构 流程图 2.流程细节 ...