自定义注解和aop结合使用---自定义日志记录的实现
2016-03-14 17:33
856 查看
关于aop和自定义注解的知识点本文不做过多阐述,相关资料可去网上查看
这篇文章就讲解的很详细http://www.cnblogs.com/shipengzhi/articles/2716004.html
这里主要写的是个人在学习aop和自定义注解时做的一个小demo,主要实现自定义日志记录的功能。
@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方),其取值有:
@Retention 用于描述注解的生命周期(即:被描述的注解在什么范围内有效),其取值有:
@Documented 在默认的情况下javadoc命令不会将我们的annotation生成再doc中去的,所以使用该标记就是告诉jdk让它也将annotation生成到doc中去
@Inherited 比如有一个类A,在他上面有一个标记annotation,那么A的子类B不用再次标记annotation就可以继承使用。
输出结果:
---->>>>>add user
插入日志记录
iam spect2
插入日志记录222
前置通知 : updateUser
----->>>>>update user
这篇文章就讲解的很详细http://www.cnblogs.com/shipengzhi/articles/2716004.html
这里主要写的是个人在学习aop和自定义注解时做的一个小demo,主要实现自定义日志记录的功能。
1、在Maven中加入以下以依赖:
<properties> <junit.version>4.12</junit.version> <spring.version>4.1.3.RELEASE</spring.version> </properties> <dependencies> <!-- 单元测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>${junit.version}</version> <scope>test</scope> </dependency> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aop</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>javax.annotation</groupId> <artifactId>jsr250-api</artifactId> <version>1.0</version> </dependency> </dependencies> <build> <plugins> <!-- java编译插件 --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
2、在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.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <context:component-scan base-package="com.annotation" ></context:component-scan> <aop:aspectj-autoproxy></aop:aspectj-autoproxy> <!-- 如果配置此项,所有注入的注解就可以使用了 --> <context:annotation-config></context:annotation-config> </beans>
3、编写自定义注解:
@Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @ interface MyLog { int value() default 11; }
@Target 用于描述注解的使用范围(即:被描述的注解可以用在什么地方),其取值有:
点击这里 | 点击这里 |
---|---|
取值 | 描述 |
CONSTRUCTOR | 用于描述构造器(领盒饭)。 |
FIELD | 用于描述域(领盒饭)。 |
LOCAL_VARIABLE | 用于描述局部变量(领盒饭)。 |
METHOD | 用于描述方法。 |
PACKAGE | 用于描述包(领盒饭)。 |
PARAMETER | 用于描述参数。 |
TYPE | 用于描述类或接口(甚至 enum )。 |
点击这里 | 点击这里 |
---|---|
取值 | 描述 |
SOURCE | 在源文件中有效(即源文件保留,领盒饭)。 |
CLASS | 在 class 文件中有效(即 class 保留,领盒饭)。 |
RUNTIME | 在运行时有效(即运行时保留)。 |
@Inherited 比如有一个类A,在他上面有一个标记annotation,那么A的子类B不用再次标记annotation就可以继承使用。
4、编写接口和实现类:
public interface UserService { public void addUser(); public void updateUser(); }
@Service("userService") public class UserServiceImpl implements UserService { @MyLog(value=110)//自定义注解 public void addUser() { System.out.println("---->>>>>add user"); } public void updateUser() { System.out.println("----->>>>>update user"); } }
5、编写切面:
@Aspect @Component public class MyAspect { @Pointcut(value = "execution(* com.annotation.*.*(..))") private void myPointCut() { } @Before("myPointCut() && @annotation(log)") public void myBefore(JoinPoint joinPoint,MyApp log) { System.out.println("前置通知 : " + joinPoint.getSignature().getName()); } public void myAfterReturning(JoinPoint joinPoint, Object ret) { System.out.println("后置通知 : " + ret); } public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable { System.out.println("前"); // 手动执行目标类 Object obj = joinPoint.proceed(); System.out.println("后"); return obj; } public void myAfterThrowing(JoinPoint joinPoint, Throwable e) { System.out.println("抛出异常 : " + e.getMessage()); } //该表达式指定com/annotation目录下及其所有子目录下的所有带有@MyLog注解的方法体为切点。 @After("myPointCut() && @annotation(log)") public void myAfter(JoinPoint joinPoint,MyLog log) throws NoSuchMethodException, SecurityException { // System.out.println(log.value()); saveLog(log); // printLog(joinPoint); } private void printLog(JoinPoint joinPoint) throws NoSuchMethodException, SecurityException { MyLog log = null; Class targetClass = joinPoint.getTarget().getClass(); String methodName = joinPoint.getSignature().getName(); Object[] arguments = joinPoint.getArgs(); Class[] parameterTypes = null; if (arguments != null) { int length = arguments.length; parameterTypes = new Class[length]; for (int i = 0; i < length; ++i) { parameterTypes[i] = arguments[i].getClass(); } } Method method = targetClass.getMethod(methodName, parameterTypes); if (method != null) { log = method.getAnnotation(MyLog.class); } if (log != null) { System.out.println("====log======" + log.value()); if(log.value()==110){ System.out.println("日志注解中的值是110"); } saveLog(log); } } private void saveLog(MyLog log) { System.out.println("插入日志记录"); System.out.println(); } }
6、编写测试用例:
@org.junit.Test public void demo1() { String xmlPath="/com/annotation/applicationContext.xml"; ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); UserService userService = (UserService) applicationContext .getBean("userService"); userService.addUser(); userService.updateUser(); }
输出结果:
---->>>>>add user
插入日志记录
iam spect2
插入日志记录222
前置通知 : updateUser
----->>>>>update user
相关文章推荐
- CentOS 7.1使用yum安装MySql5.6.24
- Linux shell命令-账户相关
- nginx的zabbix自定义监控
- CentOS7下开启端口
- vi中的撤销与重做
- CentOS 6.X安装GCC
- CentOS 7 安装 MySQL
- x4412开发板&ibox卡片电脑项目实战12-linux驱动的加载方法
- 在 CentOS/Linux 把 Kibana 3.0 部署在 Nginx 1.9.12
- CentOS配置ssh无密码登录
- linux环境ubuntu: pushd: not found
- 非常不错的文章,囊括啦高性能、高可用的分布式架构体系所有名词
- paas架构之docker——镜像管理
- Linux中gdb 查看core堆栈信息 gdb core 调试
- Nginx 502错误触发条件与解决办法汇总
- Linux平台上最常用的翻译工具—StarDict(星际译王)。
- Hadoop系列七:Hadoop之sqoop篇
- docker学习笔记:修改无法启动的容器中的内容
- Java开发必会的Linux命令
- 实现返回top功能