Spring AOP的注解实现
适用场景:
记录接口方法的执行情况,记录相关状态到日志中。
注解类: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的注解实现的更多相关文章
- spring aop 使用注解方式总结
spring aop的注解方式:和xml的配置方式略有区别,详细如下: 1.首先还是建立需要的切面类:切面类里面定义好切点配置,以及所有的需要实现的通知方法. /** * */ package com ...
- 利用Spring AOP自定义注解解决日志和签名校验
转载:http://www.cnblogs.com/shipengzhi/articles/2716004.html 一.需解决的问题 部分API有签名参数(signature),Passport首先 ...
- spring AOP自定义注解方式实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- spring AOP自定义注解 实现日志管理
今天继续实现AOP,到这里我个人认为是最灵活,可扩展的方式了,就拿日志管理来说,用Spring AOP 自定义注解形式实现日志管理.废话不多说,直接开始!!! 关于配置我还是的再说一遍. 在appli ...
- (转)利用Spring AOP自定义注解解决日志和签名校验
一.需解决的问题 部分API有签名参数(signature),Passport首先对签名进行校验,校验通过才会执行实现方法. 第一种实现方式(Origin):在需要签名校验的接口里写校验的代码,例如: ...
- 利用spring AOP 和注解实现方法中查cache-我们到底能走多远系列(46)
主题:这份代码是开发中常见的代码,查询数据库某个主表的数据,为了提高性能,做一次缓存,每次调用时先拿缓存数据,有则直接返回,没有才向数据库查数据,降低数据库压力. public Merchant lo ...
- Spring AOP的注解方式实现
spring也支持注解方式实现AOP,相对于配置文件方式,注解配置更加的轻量级,配置.修改更加方便. 1.开启AOP的注解配置方式 <!-- 开启aop属性注解 --> <aop:a ...
- Spring学习(十八)----- Spring AOP+AspectJ注解实例
我们将向你展示如何将AspectJ注解集成到Spring AOP框架.在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法. 常见AspectJ的注解: @Before – 方法 ...
- spring AOP的注解实例
上一篇写了spring AOP 的两种代理,这里开始AOP的实现了,个人喜欢用注解方式,原因是相对于XML方式注解方式更灵活,更强大,更可扩展.所以XML方式的AOP实现就被我抛弃了. 实现Sprin ...
随机推荐
- redis入门指南-附录B
- [转载]OpenStack OVS GRE/VXLAN网络
学习或者使用OpenStack普遍有这样的现象:50%的时间花费在了网络部分:30%的时间花费在了存储方面:20%的时间花费在了计算方面.OpenStack网络是不得不逾越的鸿沟,接下来我们一起尝 ...
- Java IO流之转换流
一.转换流 1.在IO包中,实际上就是分为字节流和字符流,但是除了这两个流之外,还存在了一组字节流-字符流的转换流 2.转换流用于在字节流和字符流之间转换 3.转换流本身是字符流 二.两种转换流 Ou ...
- characterEncodingFilter作用
package com.demo.test; import java.io.IOException; import javax.servlet.Filter; import javax.servlet ...
- sql 中三大范式详解
1 第一范式(1NF) 在任何一个关系数据库中,第一范式(1NF)是对关系模式的基本要求,不满足第一范式(1NF)的数据库就不是关系数据库. 所谓第一范式(1NF)是指数据库表的每一列 ...
- Coursera 机器学习笔记(二)
主要为第三周课程内容:逻辑回归与正则化 逻辑回归(Logistic Regression) 一.逻辑回归模型引入 分类问题是指尝试预测的是结果是否属于某一个类. 维基百科的定义为:根据已知训练区提供的 ...
- Docker容器管理平台Humpback进阶-私有仓库
Docker私有仓库 在 Docker 中,当我们执行 docker pull xxx 的时候,可能会比较好奇,docker 会去哪儿查找并下载镜像呢? 它实际上是从 registry.hub.doc ...
- git代码回滚
有时候我们用git提交代码后发生了错误,代码冲突了啊等等,我们需要将代码回到以前的某个版本 git代码回退有两种办法 一.git reset(推荐): 它是将最新的commit删除,用以前的某个版本的 ...
- 解决其他浏览器没有propertychange事件
监听实现: /** * Listener.js * 此类用于解决非ie下,通过js改变input的值时, * 无法触发其事件的问题(如:onpropertychange, oninput, oncha ...
- 常见web容器
当前主流的还是tomcat,jetty有较大的潜力,缩小彼此间差距,