自定义注解(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 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)的更多相关文章
- Java自定义注解的使用
什么是注解? #============================================================================================ ...
- 使用spring aspect控制自定义注解
自定义注解:这里是一个处理异常的注解,当调用方法发生异常时,返回异常信息 /** * ErrorCode: * * @author yangzhenlong * @since 2016/7/21 */ ...
- spring - 自定义注解
本自定义注解的作用:用于控制类方法的调用,只有拥有某个角色时才能调用. java内置注解 1.@Target 表示该注解用于什么地方,可能的 ElemenetType 参数包括: ElemenetTy ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- Spring 自定义注解,配置简单日志注解
java在jdk1.5中引入了注解,spring框架也正好把java注解发挥得淋漓尽致. 下面会讲解Spring中自定义注解的简单流程,其中会涉及到spring框架中的AOP(面向切面编程)相关概念. ...
- spring AOP 和自定义注解进行身份验证
一个SSH的项目(springmvc+hibernate),需要提供接口给app使用.首先考虑的就是权限问题,app要遵循极简模式,部分内容无需验证,用过滤器不能解决某些无需验证的方法 所以最终选择用 ...
- 照虎画猫写自己的Spring——自定义注解
Fairy已经实现的功能 读取XML格式配置文件,解析得到Bean 读取JSON格式配置文件,解析得到Bean 基于XML配置的依赖注入 所以,理所当然,今天该实现基于注解的依赖注入了. 基于XML配 ...
- 如何优雅地在 Spring Boot 中使用自定义注解,AOP 切面统一打印出入参日志 | 修订版
欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 资深架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...
- spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,guava限流,定时任务案例, 发邮件
本文介绍spring boot集成swagger,自定义注解,拦截器,xss过滤,异步调用,定时任务案例 集成swagger--对于做前后端分离的项目,后端只需要提供接口访问,swagger提供了接口 ...
- 使用Spring Aop自定义注解实现自动记录日志
百度加自己琢磨,以下亲测有效,所以写下来记录,也方便自己回顾浏览加深印象之类,有什么问题可以评论一起解决,不完整之处也请大佬指正,一起进步哈哈(1)首先配置文件: <!-- 声明自动为sprin ...
随机推荐
- Java设计模式知识整理
1.Java设计模式 Java设计模式分为三种类型,分别是: ①.创建型设计模式:是对对象创建过程的各种问题和解决方案的总结 包括:静态工厂模式.抽象工厂模式.单 ...
- Vue2全家桶之二:vue-router(路由)详细教程,看这个就够了
作者:东西里本文转载于:https://www.jianshu.com/p/514c7588e877来源:简书 转载仅供自己日后看方便. 由于Vue在开发时对路由支持的不足,于是官方补充了vue- ...
- vs.net2015发布web网站时,提示JsonIgnoreAttribute无法找到的解决办法
产生该问题的原因是因为项目中引用了两个版本的newtonsoft.json.dll,具体解决办法参见: 用记事本打开项目文件(*.csproj) 可以找到在这个文件中,有两处Newtonsoft.Js ...
- springcloud-hystrix断路器对微服务的容错处理
使用Hystrix实现微服务的容错处理 1.实现容错的手段 如果服务提供者响应的速度特别慢,那么消费者对提供者的请求就会强制等待,直到提供者响应或者超时.在高负载的情况下,如果不做任何处理,此类问题可 ...
- Could not autowire. No beans of 'xxxx' type found的错误
在Idea的spring工程里,经常会遇到Could not autowire. No beans of 'xxxx' type found的错误提示.但程序的编译和运行都是没有问题的,这个错误提示并 ...
- 学习PYTHON之路, DAY 9 - Socket网络编程
__import__ 两种方法,官方推荐下面的方法 Socket 参数介绍 sk.bind(address) 必会 s.bind(address) 将套接字绑定到地址.address地址的格式取决于地 ...
- one list to muti list
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8); List<List<Integer> ...
- python-shogun安装问题
- rabbitmq的问题Failed to start bean 'listenerContainer'
第一次使用mq发送消息,启动报错了,网上看了好多也没找到几个相关论坛,好几个置顶的都是发帖后不说明解决方案的.因此在这里记录一下. 原因: 因为消息监听的地址在mq服务中没有对应的q, 解决: 需要手 ...
- python之路-----MySql操作二
一.主键 1.每个 表只有一个主键 2.每个主键可以由多个列组成.(如果主键由多个组成,只要有一行列值不等即可) CREATE TABLE NAME ( id INT auto_increment, ...