适用场景:

  记录接口方法的执行情况,记录相关状态到日志中。

注解类:LogTag.java

package com.lichmama.spring.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target; @Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogTag {
String value() default "";
}

@Target (使用)注解的目标类型:

CONSTRUCTOR        构造方法声明
FIELD 字段声明(包括枚举常量)
LOCAL_VARIABLE 局部变量声明
METHOD 方法声明
PACKAGE 包声明
PARAMETER 参数声明
TYPE 类、接口(包括注释类型)或枚举声明

@Retention 注解的生命周期(默认CLASS):

CLASS       编译器将把注释记录在类文件中,但在运行时VM 不需要保留注释。
RUNTIME      编译器将把注释记录在类文件中,在运行时VM 将保留注释,因此可以反射性地读取。
SOURCE       编译器要丢弃的注释。

@Documented 标记生成javadoc

切面类:ServiceAspect.java

package com.lichmama.spring.aop;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component; import com.lichmama.spring.annotation.LogTag; @Aspect
@Component
public class ServiceAspect { private Log log = LogFactory.getLog(getClass()); @Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)")
private void pointcut() {
} @Before("pointcut()")
public void doBefore(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getMethod().getName();
String logTag = ((LogTag) signature.getMethod().getAnnotation(LogTag.class)).value();
log.info("before calling " + methodName + ", value: " + logTag);
}
}

@Pointcut("@annotation(com.lichmama.spring.annotation.LogTag)") 标注一个切入点,执行任意带有LogTag注解的方法触发。

业务实现:UserServiceImpl.java

package com.lichmama.spring.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import com.lichmama.spring.annotation.LogTag;
import com.lichmama.spring.dao.IUserDAO;
import com.lichmama.spring.entity.User;
import com.lichmama.spring.service.IUserService; @Service
public class UserServiceImpl implements IUserService { @Autowired
private IUserDAO userDAO; @LogTag
@Override
public User getUserById(int id) {
return userDAO.getUserById(id);
} @LogTag
@Override
public void saveUser(User user) {
userDAO.saveUser(user);
} @LogTag
@Override
public void updateUser(User user) {
userDAO.updateUser(user);
} @LogTag("dangerous operation")
@Override
public void deleteUser(int id) {
userDAO.deleteUser(id);
}
}

spring配置文件:applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> <context:component-scan base-package="com.lichmama.spring.aop" />
<context:component-scan base-package="com.lichmama.spring.dao" />
<context:component-scan base-package="com.lichmama.spring.service" /> <aop:aspectj-autoproxy proxy-target-class="true" />
</beans>

写个测试:

public class TestCase {

    private Log log = LogFactory.getLog(getClass());

    private ApplicationContext ctx;

    @Before
public void initSpringContext() {
ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
} @Test
public void testAOP() {
IUserService userService = ctx.getBean(IUserService.class); userService.saveUser(new User(1, "lichmama"));
userService.saveUser(new User(2, "james"));
userService.saveUser(new User(3, "dwyane")); userService.updateUser(new User(2, "bill")); User user = userService.getUserById(2);
log.info(user.toString()); userService.deleteUser(1);
}
}

16:06:22,517 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,549 INFO ServiceAspect:29 - before calling saveUser, value:
16:06:22,550 INFO ServiceAspect:29 - before calling updateUser, value:
16:06:22,551 INFO ServiceAspect:29 - before calling getUserById, value:
16:06:22,551 INFO TestSpring:35 - id: 2, name: bill
16:06:22,551 INFO ServiceAspect:29 - before calling deleteUser, value: dangerous operation

Spring AOP的注解实现的更多相关文章

  1. spring aop 使用注解方式总结

    spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...

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

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

  3. spring AOP自定义注解方式实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  4. spring AOP自定义注解 实现日志管理

    今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...

  5. (转)利用Spring AOP自定义注解解决日志和签名校验

    一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...

  6. 利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)

    主题:这份代码是开发中常见的代码,查询数据库某个主表的数据,为了提高性能,做一次缓存,每次调用时先拿缓存数据,有则直接返回,没有才向数据库查数据,降低数据库压力. public Merchant lo ...

  7. Spring AOP的注解方式实现

    spring也支持注解方式实现AOP,相对于配置文件方式,注解配置更加的轻量级,配置.修改更加方便. 1.开启AOP的注解配置方式 <!-- 开启aop属性注解 --> <aop:a ...

  8. Spring学习(十八)----- Spring AOP+AspectJ注解实例

    我们将向你展示如何将AspectJ注解集成到Spring AOP框架.在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法. 常见AspectJ的注解: @Before – 方法 ...

  9. spring AOP的注解实例

    上一篇写了spring AOP 的两种代理,这里开始AOP的实现了,个人喜欢用注解方式,原因是相对于XML方式注解方式更灵活,更强大,更可扩展.所以XML方式的AOP实现就被我抛弃了. 实现Sprin ...

随机推荐

  1. rpm不用yum安装rabbitMQ

    1.安装erlang 下载 esl-erlang_19.0~centos~6_amd64.rpm 打开https://www.erlang-solutions.com/resources/downlo ...

  2. 多线程之Parallel类

    Parallel类是对线程的一个抽象.该类位于System.Threading.Tasks名称空间中,提供了数据和任务并行性. Paraller类定义了数据并行地For和ForEach的静态方法,以及 ...

  3. 二识angularJS

    前言:记得三月份时下定决心说每天要更新一篇博客,学习点新东西,实践下来发现太不现实,生活中的事情很多,再喜欢也不能让它一件占据生活的全部吧,所以呢,以后顺其自然吧.之前有一篇'初识angular'因为 ...

  4. python爬虫从入门到放弃(七)之 PyQuery库的使用

    PyQuery库也是一个非常强大又灵活的网页解析库,如果你有前端开发经验的,都应该接触过jQuery,那么PyQuery就是你非常绝佳的选择,PyQuery 是 Python 仿照 jQuery 的严 ...

  5. INFORMATION_SCHEMA.PROFILING

    24.18 The INFORMATION_SCHEMA PROFILING Table PROFILING表提供了语句分析信息. 其内容对应于SHOW PROFILES和SHOW PROFILE语句 ...

  6. testlink(以及服务器)问题定位思路

    testlink又炸了,记录下问题定位思路: 1.翻阅logs: tail -100f ***.log 2.将关键字百度: 但是狗日的网上一般不会告诉我们这修改的文件在哪(上下图无关联,因为图是后面随 ...

  7. jquery点击非div区域隐藏div

    点击非div区域隐藏div,如图,点击圆的头像(.person-msg)弹出白色底框(.person-centre).点击圆头像以外的区域隐藏白色底框

  8. XCode 8.3 Automatically manage signing 问题

    记录iOS证书问题 无意中选择了Personal team,后台自动生成bundle identifier:com.xxx.project,导致不能在Organization team创建,而且在de ...

  9. Java之IO流详解

    IO流 Input/Output 完成输入/输出 应用程序运行时——数据在内存中  ←→ 把数据写入硬盘(磁带)  内存中的数据不可持久保存的  输入:从外部存储器(硬盘.磁带.U盘)把数据读入内存. ...

  10. NodeJS+Express+MongoDB 简单个人博客系统【Study笔记】

    Blog 个人博客系统 iBlog是在学习NodeJs时候一个练手项目Demo 系统支持用户注册/登录,内容文章查看,评论,后台管理(定制显示的分类版块,进行文章内容添加)超级管理员还可进行用户管理等 ...