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主要是在编译期或运行时,对程序进行织入,实现代理, 对原代码毫无侵入性,不破坏主要业务逻辑,减少程序的耦合度. 主要应用范围: 日志记录,性能统计,安全控制,事务处 ...
随机推荐
- How to build .apk file from command line(转)
How to build .apk file from command line Created on Wednesday, 29 June 2011 14:32 If you don’t want ...
- Maven Super POM
Maven super POM defines some properties. Three ways to find it ${M2_HOME}/lib/maven-model-builder-3. ...
- eafier 簡單易用 HTML、CSS 網頁編輯器(可自動插入 Tag 標籤)
很久很久以前,一般人要做網頁的話大概都會用 FrontPage 之類的工具,更進階一點的會用 Dreamweaver 等軟體.雖然上述軟體提供很方便的「所見即所得」的編輯預覽模式,但寫出來的網頁程式碼 ...
- Code Snippets 代码片段
Code Snippets 代码片段 1.Title : 代码片段的标题 2.Summary : 代码片段的描述文字 3.Platform : 可以使用代码片段的平台,有IOS/OS X/ ...
- java基础知识(六)日期处理
一.日期处理类 在 JDK 1.1 之前,类 Date 有两个其他的函数.它允许把日期解释为年.月.日.小时.分钟和秒值.它也允许格式化和解析日期字符串.不过,这些函数的 API 不易于实现国际化.从 ...
- 复习(1)【Maven】
终于开始复习旧知识了,有输入必然要有输出.输入和输出之间的内化过程尤为重要,在复习的同时,真正把学到的东西积淀下来,加深理解. Maven项目概念与配置 Maven是一个项目管理和综合工具.Maven ...
- JavaScript 日期选择器 Pikaday
找一些插件的过程实在太痛苦了...好容易找到一个,赶紧记录下.免得以后重复浪费时间在这上面. 插件名:Pikaday github地址:https://github.com/dbushell/Pika ...
- qt添加cef库嵌入web [转]
qt cef嵌入web 原文http://blog.sina.com.cn/s/blog_9e59cf590102vnfc.html 最近项目需要,研究了下libcef库. Cef(Chromium ...
- spring拦截器 实现应用之性能监控
package cn.ximi.erp.web.common.interceptors; import cn.ximi.core.common.utils.string.StringUtil; imp ...
- thinkpad W500S 如何换键盘?
tHINKPAD的笔记本拆装有,123456789... 至少5种以上了,一般键盘去下都是边上撬就去下 来了.今天拆换W550S键盘就遇到劲敌了.拼了 老劲也去不下,冬天背上都冒汗(屋子热的吧). 终 ...