spring-aop学习【基于注解】
我个人觉得,这个好像就是用在定制日志输出上,和log4j很像。
用途:
如果业务方法调用每一步都需要详细的日志,那就用这个吧
好处就是:
方便维护,只包含业务代码
下面开始说明:
所需要的jar包:
com.springsource.net.sf.cglib-2.2.0.jar
com.springsource.org.aopalliance-1.0.0.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar
commons-logging-1.1.1.jar
spring-aop-4.0.0.RELEASE.jar
spring-aspects-4.0.0.RELEASE.jar
spring-beans-4.0.0.RELEASE.jar
spring-context-4.0.0.RELEASE.jar
spring-core-4.0.0.RELEASE.jar
spring-expression-4.0.0.RELEASE.jar
直接上代码:
声明一个接口
package com.spring.bean.aop; import java.util.List; /**
*
* @author Administrator
*
*/
public interface UserService {
// 打招呼
void say();
// 获取年龄
int getValue(List<Integer> array,int index);
}
这是接口的实现类
package com.spring.bean.aop; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; /**
*
* @author Administrator
* 实现类
*/
@Service("userService")
public class UserServiceImpl implements UserService { /**
* 自动装配use对象
*/
@Autowired
private User user;
@Override
public void say() {
// TODO Auto-generated method stub
System.out.println("我叫"+user.getName()+",今年"+user.getAge()+"岁,你好!!");
} @Override
public int getValue(List<Integer> array, int index) {
// TODO Auto-generated method stub
return array.get(index);
} }
用户对象信息
package com.spring.bean.aop; import org.springframework.stereotype.Component; /**
* @author Administrator
* 用户信息
*/
@Component
public class User { String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
然后是两个切面代码
package com.spring.bean.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 声明一个切面
* @author Administrator
*
*/
//order可以指定哪个切面先执行,数值越小,优先执行
@Order(1)
@Aspect
@Component
public class MyLoggingAspectj { // 声明一个切入点
@Pointcut("execution(* *(..))")
public void pointcut(){ } /**
* 前置通知,该方法执行在被调用方法之前
* @param joinPoint
*/
@Before("pointcut())")
public void beforeMethod(JoinPoint joinPoint){
// 获得调用的方法名
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("MyLoggingAspectj the method "+methodName+"begins with "+Arrays.asList(args));
} }
第二个切面代码
package com.spring.bean.aop; import java.util.Arrays; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component; /**
* 声明一个切面
* @author Administrator
*
*/
@Order(2)
@Aspect
@Component
public class LoggingAspectj { // 声明一个切入点
@Pointcut("execution(* *(..))")
public void pointcut(){ } /* *//**
* 前置通知,该方法执行在被调用方法之前
* @param joinPoint
*//*
@Before("pointcut())")
public void beforeMethod(JoinPoint joinPoint){
// 获得调用的方法名
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("the method "+methodName+"begins with "+Arrays.asList(args));
} *//**
* 后置通知
* 该方法执行在被调用方法之后,报错也依然执行
* @param joinPoint
*//*
@After("pointcut())")
public void afterMethod(JoinPoint joinPoint){
// 获得调用的方法名
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("the method "+methodName+"Ends with "+Arrays.asList(args));
} *//**
* 返回通知, 在方法返回结果之后执行,异常无返回值
* @param joinPoint
*//*
@AfterReturning(value="pointcut())",returning="result")
public void afterReturning(JoinPoint joinPoint,Object result){
// 获得调用的方法名
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("the method "+methodName+"afterReturning with "+Arrays.asList(args)+" ["+result+"]");
} *//**
* 异常通知
* 在方法抛出异常之后
* @param joinPoint
*//*
@AfterThrowing(value="pointcut()",throwing="e")
public void afterReturning(JoinPoint joinPoint,Exception e){
// 获得调用的方法名
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
System.out.println("the method "+methodName+"afterThrowing with "+Arrays.asList(args)+e);
}*/ /**
* 环绕通知需要配合ProceedingJoinPoint使用,相当于动态代理
* @param pjp
* @return
*/
@Around(value="pointcut()")
public Object aroundMethod(ProceedingJoinPoint pjp) {
// 获得调用的方法名
String methodName = pjp.getSignature().getName();
Object result = null;
// 调用目标方法
try {
// 前置通知
System.out.println("the method " + methodName + "Begins with " + Arrays.asList(pjp.getArgs()));
result = pjp.proceed();
// 后置通知
System.out.println("the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()));
// 后置有返回值
System.out.println(
"the method " + methodName + "Ends with " + Arrays.asList(pjp.getArgs()) + " [" + result + "]");
} catch (Throwable e) {
// TODO Auto-generated catch block
// 异常通知
System.out.println("the method " + methodName + "AfterThrowing with " + Arrays.asList(pjp.getArgs()) + e);
// e.printStackTrace();
// 不加这句,会报错,因为result返回值为null
throw new RuntimeException(e);
}
System.out.println("the method " + methodName + "LastEnds with " + Arrays.asList(pjp.getArgs()));
return result;
} }
测试代码:
package com.spring.bean.aop; import java.util.ArrayList;
import java.util.List; import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ctx=new ClassPathXmlApplicationContext("bean-aop.xml");
UserService userServiceImpl=(UserService) ctx.getBean("userService");
User user=(User) ctx.getBean("user");
List<Integer> arrayList = new ArrayList<Integer>();
arrayList.add(1);
arrayList.add(2);
int age = userServiceImpl.getValue(arrayList, 1);
user.setName("xiaoqiang");
user.setAge(age);
userServiceImpl.say();
} }
bean文件
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:p="http://www.springframework.org/schema/p"
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-4.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 自动扫描的包 -->
<context:component-scan base-package="com.spring.bean.aop"></context:component-scan>
<!-- 使 AspectJ 的注解起作用 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy> </beans>
总结:
1.在pom文件添加依赖,在 Spring 的配置文件中加入 aop 的命名空间。
<!--使用AspectJ方式注解需要相应的包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>${aspectj.version}</version>
</dependency>
<!--使用AspectJ方式注解需要相应的包-->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>${aspectj.version}</version>
</dependency>
2.为接口实现类添加注解@Component
3.编写一个切面类,配置切面
* 3.1 在配置文件中配置自动扫描的包: <context:component-scan base-package="com.spring.bean.aop"></context:component-scan>
* 3.2 加入使 AspjectJ 注解起作用的配置: <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
* 为匹配的类自动生成动态代理对象.
4.编写前置通知方法,在方法上方添加注解
// 表达式注意格式: 修饰 +方法(有无返回)+包名+类名+方法名+参数
@Before("execution(public int com.spring.bean.annotation.aopimpl.Calculation.sub(int, int))")
* @Before 表示在目标方法执行之前执行 @Before 标记的方法的方法体.
* @Before 里面的是切入点表达式:
如关注详细参数,添加joinpoint对象,可以访问到方法的签名和参数
spring-aop学习【基于注解】的更多相关文章
- SSM框架—Spring AOP之基于注解的声明式AspectJ(Demo)
项目结构 XML <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...
- Spring AOP 学习例子
http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example 工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...
- 在Intellij上面导入项目 & AOP示例项目 & AspectJ学习 & Spring AoP学习
为了学习这篇文章里面下载的代码:http://www.cnblogs.com/charlesblc/p/6083687.html 需要用Intellij导入一个已有工程.源文件原始内容也可见:link ...
- 运用Spring Aop,一个注解实现日志记录
运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...
- 使用 Spring 2.5 基于注解驱动的 Spring MVC
http://www.ibm.com/developerworks/cn/java/j-lo-spring25-mvc/ 概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Sp ...
- 使用 Spring 2.5 基于注解驱动的 Spring MVC--转
概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...
- Spring框架学习之注解配置与AOP思想
上篇我们介绍了Spring中有关高级依赖关系配置的内容,也可以调用任意方法的返回值作为属性注入的值,它解决了Spring配置文件的动态性不足的缺点.而本篇,我们将介绍Spring的又一大核心 ...
- 一步一步深入spring(5)--使用基于注解的spring实现 AOP
1.要利用spring aop,至少需要添加以下jar包 使用spring需要的jarspring.jar .commons-logging.jar 使用切面编程(AOP)需要的jar aspectj ...
- spring aop学习记录
许多AOP框架,比较常用的是Spring AOP 与AspectJ.这里主要学习的Spring AOP. 关于AOP 日志.事务.安全验证这些通用的.散步在系统各处的需要在实现业务逻辑时关注的事情称为 ...
- AOP和spring AOP学习记录
AOP基本概念的理解 面向切面AOP主要是在编译期或运行时,对程序进行织入,实现代理, 对原代码毫无侵入性,不破坏主要业务逻辑,减少程序的耦合度. 主要应用范围: 日志记录,性能统计,安全控制,事务处 ...
随机推荐
- Timequest收集命令
表 1. 收集命令 命令 说明 all_clocks 返回设计中所有时钟的收集. all_inputs 返回设计中输入端口的收集. all_outputs 返回设计中所有寄存器的收集. get_cel ...
- XML基础
什么是XML? XML(Extensible Markup Language)可扩展标记语言,是一种以简单文本格式存储数据的方式. 它最重要的组成部分是XML元素,包含了文档的实际数据. XML的几个 ...
- 移动端web开发的一些知识点
整理一下自己平时移动端web开发中遇到的问题,也参考一下前辈的一些总结 1.最常见的要数1像素边框了 因为Retine屏的分辨率始终是普通屏幕的2倍,1px的边框在dpr=2的retina屏下会显示成 ...
- Android Studio 导出jar包
不像在Eclipse,可以直接导出jar包.AndroidStudio只可以生成aar包. 在网上看到许多朋友问怎么可以像Eclipse一样导出jar包,其实我们只要知道它的原理就可以了. 用jar命 ...
- PXE+Kickstart+DHCP+TFTP实现无人值守安装操作系统
PXE+Kickstart+DHCP+TFTP实现无人值守安装操作系统 PXE + Kickstart PXE的工作流程及配置文件 Kickstart的配置文件 Linux安装大致可以分为2个阶段 第 ...
- Qt拖拽界面 (*.ui) 缩放问题及解决办法
问题 使用Qt Designer 设计的界面,在缩放的时候不能随着主窗口一起缩放. 解决办法 之前遇到这个问题的时候,都是直接重写resizeEvent接口来实现的,在自动生成的Ui_Widget或U ...
- C语言 完美字符串
约翰认为字符串的完美度等于它里面所有字母的完美度之和.每个字母的完美度可以由你来分配,不同字母的完美度不同,分别对应一个1-26之间的整数. 约翰不在乎字母大小写.(也就是说字母F和f)的完美度相同. ...
- zepto返回顶部动画
点击返回顶部 function goTop(acceleration, time) { acceleration = acceleration || 0.1; time = time || 16; v ...
- #Java编程思想笔记(一)——static
Java编程思想笔记(一)--static 看<Java编程思想>已经有一段时间了,一直以来都把笔记做在印象笔记上,今天开始写博客来记录. 第一篇笔记来写static关键字. static ...
- C/C++: C++可调用对象详解
C++中有几种可调用对象:函数,函数指针,lambda表达式,bind创建的对象,以及重载了函数调用符的类. 1. 函数 函数偏基础的东西,在这里不再叙述.重点讲下C++11的某些重要特性和函数指针. ...