我个人觉得,这个好像就是用在定制日志输出上,和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学习【基于注解】的更多相关文章

  1. SSM框架—Spring AOP之基于注解的声明式AspectJ(Demo)

    项目结构 XML <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http ...

  2. Spring AOP 学习例子

    http://outofmemory.cn/code-snippet/3762/Spring-AOP-learn-example     工作忙,时间紧,不过事情再多,学习是必须的.记得以前的部门老大 ...

  3. 在Intellij上面导入项目 & AOP示例项目 & AspectJ学习 & Spring AoP学习

    为了学习这篇文章里面下载的代码:http://www.cnblogs.com/charlesblc/p/6083687.html 需要用Intellij导入一个已有工程.源文件原始内容也可见:link ...

  4. 运用Spring Aop,一个注解实现日志记录

    运用Spring Aop,一个注解实现日志记录 1. 介绍 我们都知道Spring框架的两大特性分别是 IOC (控制反转)和 AOP (面向切面),这个是每一个Spring学习视频里面一开始都会提到 ...

  5. 使用 Spring 2.5 基于注解驱动的 Spring MVC

    http://www.ibm.com/developerworks/cn/java/j-lo-spring25-mvc/ 概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Sp ...

  6. 使用 Spring 2.5 基于注解驱动的 Spring MVC--转

    概述 继 Spring 2.0 对 Spring MVC 进行重大升级后,Spring 2.5 又为 Spring MVC 引入了注解驱动功能.现在你无须让 Controller 继承任何接口,无需在 ...

  7. Spring框架学习之注解配置与AOP思想

         上篇我们介绍了Spring中有关高级依赖关系配置的内容,也可以调用任意方法的返回值作为属性注入的值,它解决了Spring配置文件的动态性不足的缺点.而本篇,我们将介绍Spring的又一大核心 ...

  8. 一步一步深入spring(5)--使用基于注解的spring实现 AOP

    1.要利用spring aop,至少需要添加以下jar包 使用spring需要的jarspring.jar .commons-logging.jar 使用切面编程(AOP)需要的jar aspectj ...

  9. spring aop学习记录

    许多AOP框架,比较常用的是Spring AOP 与AspectJ.这里主要学习的Spring AOP. 关于AOP 日志.事务.安全验证这些通用的.散步在系统各处的需要在实现业务逻辑时关注的事情称为 ...

  10. AOP和spring AOP学习记录

    AOP基本概念的理解 面向切面AOP主要是在编译期或运行时,对程序进行织入,实现代理, 对原代码毫无侵入性,不破坏主要业务逻辑,减少程序的耦合度. 主要应用范围: 日志记录,性能统计,安全控制,事务处 ...

随机推荐

  1. Excel—利用散点图计算相关系数

    1.建立数组 2.创建散点图. 3.添加趋势线. 4.设立为线性函数,勾选显示公式.显示R^2值,R即为相关系数. 5. 备注:此外也可以使用=CORREL()函数对相关系数进行求值.其结果是一致的.

  2. JS 函数的柯里化与反柯里化

    ===================================== 函数的柯里化与反柯里化 ===================================== [这是一篇比较久之前的总 ...

  3. STM32f103 定时器之编码器接口模式

    背景 买了个Arduino的旋转编码器模块,配合STM32定时器的编码器模式实现了旋转角度以及圈数的计数.这种旋转编码器我能想到的实际应用场景暂时只有实体音量旋钮,鼠标的滚轮等,所以只实现了计数.阅读 ...

  4. Fiddler将笔记本设置代理,抓取手机网络请求包

    第一步:下载fiddler,下载地址:http://www.telerik.com/download/fiddler 第二步:安装fiddler,略过... 第三步:启动fiddler,启动后界面如下 ...

  5. postgresql中的CUBE函数

    数据函数简介添加汇总额外信息 数据 --复杂统计函数 CREATE TABLE t3 (color_type varchar(20), in_date varchar(30),color_count ...

  6. Delphi XE7中各种字符串与字符类型的内存结构

    1. ShortString 类型 定义:type ShortString = string[255]; 内存结构与大小:ShortString 是每个字符为单字节的字符串.ShortString 的 ...

  7. php多线程操作同一文件-待续

    同意文件操作同意文件的问题在于逻辑有些地方不合适,如果多个线程同时写入,在不加锁的情况下,可能导致得到结果不如意,为了安全,和脏读(数据库的词),应该使用排他锁,这就意味着每次只能被一个线程操作.其他 ...

  8. HTML5复习整理

    一.推出的目标 web浏览器兼容性低:文档结构不明确:web应用程序的功能受限 二.语法的改变 内容类型(html或htm):DOCTYPE声明简化:指定字符编码简化:可以省略标记的元素:具有Bool ...

  9. 关于angularjs指令

    一个指令用来引入新的HTML语法.指令是DOM元素上的标记,使元素拥有特定的行为.举例来说,静态的HTML不知道如何来创建和展现一个日期选择器控件.让HTML能识别这个语法,我们需要使用指令.指令通过 ...

  10. linux文件对比命令——diff

    diff用于比较文件或目录内容,特别是比较两个版本不同的文件以找到改动的地方. 如果指定比较的是文件,则只有当输入为文本文件时才有效,以逐行的方式,比较文本文件的异同处. 如果指定比较的是目录的的时候 ...