我个人觉得,这个好像就是用在定制日志输出上,和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. fedora配置163为yum的源

    一种方法: 1.下载  http://mirrors.163.com/.help/fedora-163.repo 和 http://mirrors.163.com/.help/fedora-updat ...

  2. Python 自动化入门 day1复习

    一.Python介绍 Python是1989年圣诞节期间龟叔创造的一种解释型语言. 最新的TIOBE排行榜 目前Python主要应用领域: 云计算: 云计算最火的语言, 典型应用OpenStack W ...

  3. 第3月第19天 cxx_destruct dispatch_get_main_queue()死锁

    1. http://blog.jobbole.com/65028/ 2. - (void)viewDidLoad { [super viewDidLoad]; NSLog("); dispa ...

  4. saltstack 把数据返回到mysql服务器

    环境:http://www.cnblogs.com/zzzhfo/p/5790918.html master端需要安装MySQL-python和mysql-server mysql-server用于存 ...

  5. Maximal Rectangle

    很不好想的一道题,参考:http://blog.csdn.net/doc_sgl/article/details/11832965 分为两步:把原矩阵转为直方图,再用largest rectangle ...

  6. 通过ip查询对方位置

    我们这里使用的是baidumap的高精度IP定位API的接口,具体说明可以参考baidu提供的文档 使用前需要申请一个AK密钥类似于Kgcx......................xxl8w的样式 ...

  7. CodeIgniter 3 源码学习笔记《一》

    CodeIgniter 是一套给 PHP 网站开发者使用的应用程序开发框架和工具包. 它的目标是让你能够更快速的开发,它提供了日常任务中所需的大量类库, 以及简单的接口和逻辑结构.通过减少代码量,Co ...

  8. Swift 备忘单和快速参考

    Variables var myInt = var myExplicitInt: Int = // explicit type var x = , y = , z = // declare multi ...

  9. C#可空类型

    C#创建可空类型对于有些可选类型的时候特别好用.创建可空类型用法直接上图. 执行效果 用法 运行效果

  10. Redis的Python实践,以及四中常用应用场景详解——学习董伟明老师的《Python Web开发实践》

    首先,简单介绍:Redis是一个基于内存的键值对存储系统,常用作数据库.缓存和消息代理. 支持:字符串,字典,列表,集合,有序集合,位图(bitmaps),地理位置,HyperLogLog等多种数据结 ...