Spring aop 实例(转)

  面向切面编程,有效的降低了代码之间的耦合性,易于维护;例如:我们习惯在代码中加上一些日志信息,在程序出错时方便快速查找找到问题,通常做法是在请求进入方法的时候打印日志,退出前打印日志,还有在出错时打印日志,那么问题就来了,每个方法中都需要打印日志,这些相同的部分就可以当做一个切面,通过配置切点来触发所需要的功能,比如,我需要在请求进入方法的时候打印,即可使用aop当中的前置通知来做到,这样就不需要每个方法中都去写一遍,配置好之后引用即可。

  简单的记录一下spring aop的一个示例

  基于两种配置方式:

      1:基于xml配置

      2:基于注解配置

  这个例子是模拟对数据库的更改操作添加事物

  其实并没有添加,只是简单的输出了一下记录

  首先看下整个例子的目录图

  

全部代码就不贴了,数目有点多,不过很简单,看一部分就能够明白

第一种配置方式

  基于xml方式配置

  首先将service,dao注册到spring容器

  

  配置一下扫描包还是很方便的

  接下来看下service 

 1 package com.yangxin.core.service.impl;
 2
 3 import org.springframework.beans.factory.annotation.Autowired;
 4 import org.springframework.stereotype.Service;
 5
 6 import com.yangxin.core.dao.UserDao;
 7 import com.yangxin.core.pojo.User;
 8 import com.yangxin.core.service.UserService;
 9
10 @Service
11 public class UserServiceImpl implements UserService {
12
13     @Autowired
14     private UserDao userDao;
15
16     @Override
17     public void addUser(User user) {
18         userDao.insertUser(user);
19         System.out.println("添加成功");
20     }
21
22     @Override
23     public void deleteUser(String name) {
24         userDao.deteleUser(name);
25         System.out.println("删除成功");
26     }
27
28 }

要做的事情很简单,插入一条数据,删除一条数据

接下来看下切面代码

 1 package com.yangxin.core.transaction;
 2
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4
 5 import com.yangxin.core.pojo.User;
 6
 7 public class TransactionDemo {
 8
 9     //前置通知
10     public void startTransaction(){
11         System.out.println("begin transaction ");
12     }
13
14     //后置通知
15     public void commitTransaction(){
16         System.out.println("commit transaction ");
17     }
18
19     //环绕通知
20     public void around(ProceedingJoinPoint joinPoint) throws Throwable{
21         System.out.println("begin transaction");
22         //调用process()方法才会真正的执行实际被代理的方法
23         joinPoint.proceed();
24
25         System.out.println("commit transaction");
26     }
27
28 }

然后看下这个切面在applicationContext.xml中是如何配置的

 1 <aop:config>
 2         <aop:pointcut expression="execution(* com.yangxin.core.service.*.*.*(..))" id="p1" />
 3
 4         <aop:aspect ref = "transactionDemo">
 5
 6         <aop:before method="startTransaction" pointcut-ref="p1" />
 7
 8         <aop:after-returning method="commitTransaction" pointcut-ref="p1"/>
 9
10         </aop:aspect>
11     </aop:config>

这里没有演示环绕通知

好了,运行测试代码

测试代码如下

 1   @Test
 2     public void test1(){
 3         ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
 4
 5         UserService userService = applicationContext.getBean(UserService.class);
 6
 7         User user = new User();
 8
 9         user.setAge(19);
10         user.setName("yangxin");
11
12         userService.addUser(user);
13         userService.deteleUser("yangxin");
1415
16     }

控制台输出如下

  begin transaction

  添加成功

  commit transaction

  begin transaction

  删除成功

  commit transaction

现在来测试一下环绕通知

修改一下applicationContext.xml中的配置切面那一部分

修改后的代码

1 <aop:config>
2         <aop:pointcut expression="execution(* com.yangxin.core.service.*.*.*(..))" id="p1" />
3
4         <aop:aspect ref = "transactionDemo">
5
6         <aop:around method="around" pointcut-ref="p1"/>
7
8         </aop:aspect>
9     </aop:config>

运行测试代码

输出如下

begin transaction
添加成功
commit transaction
begin transaction
删除成功
commit transaction

好了,现在贴下如何用注解的方法

贴下基于注解的切面的代码

 1 package com.yangxin.core.transaction;
 2
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.AfterReturning;
 5 import org.aspectj.lang.annotation.Around;
 6 import org.aspectj.lang.annotation.Aspect;
 7 import org.aspectj.lang.annotation.Before;
 8 import org.aspectj.lang.annotation.Pointcut;
 9
10 @Aspect
11 public class TransactionDemo2 {
12
13     @Pointcut(value="execution(* com.yangxin.core.service.*.*.*(..))")
14     public void point(){
15
16     }
17
18     @Before(value="point()")
19     public void before(){
20         System.out.println("transaction begin");
21     }
22
23     @AfterReturning(value = "point()")
24     public void after(){
25         System.out.println("transaction commit");
26     }
27
28     @Around("point()")
29     public void around(ProceedingJoinPoint joinPoint) throws Throwable{
30         System.out.println("transaction begin");
31         joinPoint.proceed();
32         System.out.println("transaction commit");
33
34     }
35 }

在applicationContext.xml中配置

1 <bean id = "transactionDemo2" class = "com.yangxin.core.transaction.TransactionDemo2" />
1 <aop:aspectj-autoproxy />

测试步骤和以上一致,这里就不贴了

结合例子我们来看看这些核心的概念:

  2.1、切面(Aspect):是一个类,里面定义了通知与切点。

  2.2、切点(PointCut):表达式。就是告诉程序要在执行哪些核心业务的时候,执行非核心的业务。

  2.3、通知(advice):五种通知方式:

    • @Before:前置通知,在调用目标方法之前执行通知定义的任务
    • @After:后置通知,在目标方法执行结束后,无论执行结果如何都执行通知定义的任务
    • @After-returning:后置通知,在目标方法执行结束后,如果执行成功,则执行通知定义的任务
    • @After-throwing:异常通知,如果目标方法执行过程中抛出异常,则执行通知定义的任务
    • @Around:环绕通知,在目标方法执行前和执行后,都需要执行通知定义的任务。

原文地址:https://www.cnblogs.com/myseries/p/10800215.html

时间: 2024-10-11 19:37:44

Spring aop 实例(转)的相关文章

Spring Aop实例之AspectJ注解配置

http://blog.csdn.net/xiaoxian8023/article/details/17285809 上篇博文<Spring Aop实例之xml配置>中,讲解了xml配置方式,今天来说说AspectJ注解方式去配置spring aop. 依旧采用的jdk代理,接口和实现类代码请参考上篇博文.主要是将Aspect类分享一下: [java] view plaincopy package com.tgb.aop; import org.aspectj.lang.JoinPoint;

Spring AOP实例——异常处理和记录程序执行时间

实例简介: 这个实例主要用于在一个系统的所有方法执行过程中出线异常时,把异常信息都记录下来,另外记录每个方法的执行时间. 用两个业务逻辑来说明上述功能,这两个业务逻辑首先使用Spring AOP的自动代理功能,然后一个用Java的动态代理,一个用CGLIB代理. 实现思路: 首先定义负责异常处理的Advice:ExceptionHandler.java,定义记录程序执行时间的Advice:TimeHandler.java 然后定义业务逻辑接口LogicInterface.java,编写实现业务逻

Spring Aop实例

在上篇博文中,我向大家介绍了Aop重要概念和教程,这回给出代码示例. 一.XML方式 1. TestAspect:切面类 [java] view plaincopy package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class TestAspect { public void doAfter(JoinPoint jp) { S

Spring Aop实例之xml配置

上篇博文<3幅图让你了解Spring AOP>中介绍了aop通知类型,AOP的配置方式有2种方式:xml配置和AspectJ注解方式.今天我们就来实践一下xml配置方式. http://blog.csdn.net/xiaoxian8023/article/details/17258933 我采用的jdk代理,所以首先将接口和实现类代码附上 [java] view plaincopy package com.tgb.aop; public interface UserManager { publ

spring aop实例介绍

在Spring 2.0中,Pointcut的定义包括两个部分:Pointcut表示式(expression)和Pointcut签名(signature).让我们先看看execution表示式的格式:括号中各个pattern分别表示修饰符匹配(modifier-pattern?).返回值匹配(ret-type-pattern).类路径匹配(declaring-type-pattern?).方法名匹配(name-pattern).参数匹配((param-pattern)).异常类型匹配(throws

spring Aop 实例

SpringMvc.xml中添加扫描日志类和使用aop注解. <!--扫描全局日志 --> <context:component-scan base-package="com.company.wx.log" /> <aop:aspectj-autoproxy expose-proxy="true"/> 配置类: @Aspect @Component public class GlobalLogConfig { @Autowired

浅谈Spring(四)AOP实例

在<浅谈Spring(三)AOP原理>中我详细的介绍了AOP的基本概念和实现原理,这里给出代码示例. 一.XML方式 1. TestAspect:切面类 package com.spring.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; public class TestAspect { public void doAfter(JoinPoint jp) { System

spring aop简单日志实例

转载自:http://www.blogjava.net/laoding/articles/242611.html 一直就用spring的IOC,遗憾spring的另一重要组成部分AOP却没用过,所以近几天抽空研究了下AOP,学了些东西,在这里记录下spring2.0的aop配置,以一个简单的记录日志的实例来说明,先介绍下用XMLSchema来配置,下一篇介绍annotation配置,废话不多说,开始吧先新建个web工程,将spring的包加进去,为方便就把全部的jar包加进去. 先来看个接口,很

Spring中AOP实例详解

Spring中AOP实例详解 需要增强的服务 假如有以下service,他的功能很简单,打印输入的参数并返回参数. @Service public class SimpleService { public String getName(String name) { System.out.println(get name is: + name); return name; } } 定义切面和切点 @Component @Aspect public class L ogAspect { // 定义切