Spring 之AOP 详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Spring 之AOP 详解相关的知识,希望对你有一定的参考价值。

 

第一节:AOP 简介

 

AOP 简介:百度百科;

面向切面编程(也叫面向方面编程):Aspect Oriented Programming(AOP),是软件开发中的一个热点,也是Spring框架中的一个重要内容。利用AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

主要的功能是:日志记录,性能统计,安全控制,事务处理,异常处理等等。

 --------

这里我先开头讲一个例子代码程序:

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.junit.Before;
 4 import org.junit.Test;
 5 import org.springframework.context.ApplicationContext;
 6 import org.springframework.context.support.ClassPathXmlApplicationContext;
 7 
 8 import com.wishwzp.service.StudentService;
 9 
10 
11 public class T {
12 
13     private ApplicationContext ac;
14 
15     @Before
16     public void setUp() throws Exception {
17         ac=new ClassPathXmlApplicationContext("beans.xml");
18     }
19 
20     @Test
21     public void test1() {
22         StudentService studentService=(StudentService)ac.getBean("studentService");
23         studentService.addStudent("张三");
24     }
25     
26 
27 }

 

beans.xml:

1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4     xsi:schemaLocation="http://www.springframework.org/schema/beans
5         http://www.springframework.org/schema/beans/spring-beans.xsd">
6     
7     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
8     
9 </beans>

 

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public void addStudent(String name) {
 9         System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         System.out.println("完成学生"+name+"的添加");
12     }
13 
14 }

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public void addStudent(String name);
6 }

 

运行结果显示:

开始添加学生张三
添加学生张三
完成学生张三的添加

--------------

 

 

 

 

 

 

第二节:Spring AOP 实例

 

1,前置通知;

2,后置通知;

3,环绕通知;

4,返回通知;

5,异常通知;

 

1,前置通知;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.wishwzp.service.StudentService;
 7 
 8 
 9 public class T {
10 
11     public static void main(String[] args) {
12         ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
13         StudentService studentService=(StudentService)ac.getBean("studentService");
14         studentService.addStudent("张三");
15         
16     }
17 }

 

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     
10     <!-- 注入bean,StudentServiceAspect -->
11     <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean>
12     
13     <!-- 注入bean,StudentServiceImpl -->
14     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
15     
16     <!-- 配置AOP -->
17     <aop:config>
18         <aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
19             <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/>
20             <aop:before method="doBefore" pointcut-ref="businessService"/>
21         </aop:aspect> 
22     </aop:config>
23 </beans>

StudentServiceAspect.java:

 1 package com.wishwzp.advice;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 public class StudentServiceAspect {
 7 
 8     public void doBefore(JoinPoint jp){
 9         System.out.println("类名:"+jp.getTarget().getClass().getName());
10         System.out.println("方法名:"+jp.getSignature().getName());
11         System.out.println("开始添加学生:"+jp.getArgs()[0]);
12     }
13     
14 }

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public void addStudent(String name) {
 9         // System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         // System.out.println("完成学生"+name+"的添加");
12     }
13 
14 }

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public void addStudent(String name);
6 }

 

运行结果显示:

类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生张三

 

 

2,后置通知;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.wishwzp.service.StudentService;
 7 
 8 
 9 public class T {
10 
11     public static void main(String[] args) {
12         ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
13         StudentService studentService=(StudentService)ac.getBean("studentService");
14         studentService.addStudent("张三");
15         
16     }
17 }

 

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     
10     <!-- 注入bean,StudentServiceAspect -->
11     <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean>
12     
13     <!-- 注入bean,StudentServiceImpl -->
14     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
15     
16     <!-- 配置AOP -->
17     <aop:config>
18         <aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
19             <!-- 配置执行切点路径和id -->
20             <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/>
21             <!-- 前置通知 -->
22             <aop:before method="doBefore" pointcut-ref="businessService"/>
23             <!-- 后置通知 -->
24             <aop:after method="doAfter" pointcut-ref="businessService"/>
25         </aop:aspect> 
26     </aop:config>
27 </beans>

StudentServiceAspect.java:

 1 package com.wishwzp.advice;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 public class StudentServiceAspect {
 7 
 8     //前置通知
 9     public void doBefore(JoinPoint jp){
10         System.out.println("类名:"+jp.getTarget().getClass().getName());
11         System.out.println("方法名:"+jp.getSignature().getName());
12         System.out.println("开始添加学生:"+jp.getArgs()[0]);
13     }
14     
15     //后置通知
16     public void doAfter(JoinPoint jp){
17         System.out.println("类名:"+jp.getTarget().getClass().getName());
18         System.out.println("方法名:"+jp.getSignature().getName());
19         System.out.println("学生添加完成:"+jp.getArgs()[0]);
20     }
21 }

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public void addStudent(String name) {
 9         // System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         // System.out.println("完成学生"+name+"的添加");
12     }
13 
14 }

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public void addStudent(String name);
6 }

 

运行结果显示:

类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生张三
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三

 

 

3,环绕通知;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.wishwzp.service.StudentService;
 7 
 8 
 9 public class T {
10 
11     public static void main(String[] args) {
12         ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
13         StudentService studentService=(StudentService)ac.getBean("studentService");
14         studentService.addStudent("张三");
15         
16     }
17 }

 

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     
10     <!-- 注入bean,StudentServiceAspect -->
11     <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean>
12     
13     <!-- 注入bean,StudentServiceImpl -->
14     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
15     
16     <!-- 配置AOP -->
17     <aop:config>
18         <aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
19             <!-- 配置执行切点路径和id -->
20             <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/>
21             <!-- 前置通知 -->
22             <aop:before method="doBefore" pointcut-ref="businessService"/>
23             <!-- 后置通知 -->
24             <aop:after method="doAfter" pointcut-ref="businessService"/>
25             <!-- 环绕通知 -->
26             <aop:around method="doAround" pointcut-ref="businessService"/>
27         </aop:aspect> 
28     </aop:config>
29 </beans>

StudentServiceAspect.java:

 1 package com.wishwzp.advice;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 public class StudentServiceAspect {
 7 
 8     //前置通知
 9     public void doBefore(JoinPoint jp){
10         System.out.println("类名:"+jp.getTarget().getClass().getName());
11         System.out.println("方法名:"+jp.getSignature().getName());
12         System.out.println("开始添加学生:"+jp.getArgs()[0]);
13     }
14     
15     //后置通知
16     public void doAfter(JoinPoint jp){
17         System.out.println("类名:"+jp.getTarget().getClass().getName());
18         System.out.println("方法名:"+jp.getSignature().getName());
19         System.out.println("学生添加完成:"+jp.getArgs()[0]);
20     }
21     
22     //环绕通知,这里添加了返回值
23     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
24         System.out.println("添加学生前");
25         Object retVal=pjp.proceed();
26         System.out.println(retVal);
27         System.out.println("添加学生后");
28         return retVal;
29     }
30 }

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public String addStudent(String name) {
 9         // System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         // System.out.println("完成学生"+name+"的添加");
12         return name;
13     }
14 
15 }

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public String addStudent(String name);
6 }

 

运行结果显示:

类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生前
添加学生张三
张三
添加学生后
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三

 

 

 

4,返回通知;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.wishwzp.service.StudentService;
 7 
 8 
 9 public class T {
10 
11     public static void main(String[] args) {
12         ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
13         StudentService studentService=(StudentService)ac.getBean("studentService");
14         studentService.addStudent("张三");
15         
16     }
17 }

 

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     
10     <!-- 注入bean,StudentServiceAspect -->
11     <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean>
12     
13     <!-- 注入bean,StudentServiceImpl -->
14     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
15     
16     <!-- 配置AOP -->
17     <aop:config>
18         <aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
19             <!-- 配置执行切点路径和id -->
20             <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/>
21             <!-- 前置通知 -->
22             <aop:before method="doBefore" pointcut-ref="businessService"/>
23             <!-- 后置通知 -->
24             <aop:after method="doAfter" pointcut-ref="businessService"/>
25             <!-- 环绕通知 -->
26             <aop:around method="doAround" pointcut-ref="businessService"/>
27             <!-- 返回通知 -->
28             <aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/>
29         </aop:aspect> 
30     </aop:config>
31 </beans>

StudentServiceAspect.java:

 1 package com.wishwzp.advice;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 public class StudentServiceAspect {
 7 
 8     //前置通知
 9     public void doBefore(JoinPoint jp){
10         System.out.println("类名:"+jp.getTarget().getClass().getName());
11         System.out.println("方法名:"+jp.getSignature().getName());
12         System.out.println("开始添加学生:"+jp.getArgs()[0]);
13     }
14     
15     //后置通知
16     public void doAfter(JoinPoint jp){
17         System.out.println("类名:"+jp.getTarget().getClass().getName());
18         System.out.println("方法名:"+jp.getSignature().getName());
19         System.out.println("学生添加完成:"+jp.getArgs()[0]);
20     }
21     
22     //环绕通知,这里添加了返回值
23     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
24         System.out.println("添加学生前");
25         Object retVal=pjp.proceed();
26         System.out.println(retVal);
27         System.out.println("添加学生后");
28         return retVal;
29     }
30     
31     //返回通知
32     public void doAfterReturning(JoinPoint jp){
33         System.out.println("返回通知");
34     }
35 }

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public String addStudent(String name) {
 9         // System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         // System.out.println("完成学生"+name+"的添加");
12         return name;
13     }
14 
15 }

 

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public String addStudent(String name);
6 }

 

运行结果显示:

类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
开始添加学生:张三
添加学生前
添加学生张三
返回通知
张三
添加学生后
类名:com.wishwzp.service.impl.StudentServiceImpl
方法名:addStudent
学生添加完成:张三

 

5,异常通知;

T.java:

 1 package com.wishwzp.test;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 import com.wishwzp.service.StudentService;
 7 
 8 
 9 public class T {
10 
11     public static void main(String[] args) {
12         ApplicationContext ac=new ClassPathXmlApplicationContext("beans.xml");
13         StudentService studentService=(StudentService)ac.getBean("studentService");
14         studentService.addStudent("张三");
15         
16     }
17 }

 

beans.xml:

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:aop="http://www.springframework.org/schema/aop"
 5     xsi:schemaLocation="http://www.springframework.org/schema/beans
 6         http://www.springframework.org/schema/beans/spring-beans.xsd
 7         http://www.springframework.org/schema/aop
 8         http://www.springframework.org/schema/aop/spring-aop.xsd">
 9     
10     <!-- 注入bean,StudentServiceAspect -->
11     <bean id="studentServiceAspect" class="com.wishwzp.advice.StudentServiceAspect"></bean>
12     
13     <!-- 注入bean,StudentServiceImpl -->
14     <bean id="studentService" class="com.wishwzp.service.impl.StudentServiceImpl"></bean>
15     
16     <!-- 配置AOP -->
17     <aop:config>
18         <aop:aspect id="studentServiceAspect" ref="studentServiceAspect">
19             <!-- 配置执行切点路径和id -->
20             <aop:pointcut expression="execution(* com.wishwzp.service.*.*(..))" id="businessService"/>
21             <!-- 前置通知 -->
22             <aop:before method="doBefore" pointcut-ref="businessService"/>
23             <!-- 后置通知 -->
24             <aop:after method="doAfter" pointcut-ref="businessService"/>
25             <!-- 环绕通知 -->
26             <aop:around method="doAround" pointcut-ref="businessService"/>
27             <!-- 返回通知 -->
28             <aop:after-returning method="doAfterReturning" pointcut-ref="businessService"/>
29             <!-- 异常通知 -->
30             <aop:after-throwing method="doAfterThrowing" pointcut-ref="businessService" throwing="ex"/>
31         </aop:aspect> 
32     </aop:config>
33 </beans>

StudentServiceAspect.java:

 1 package com.wishwzp.advice;
 2 
 3 import org.aspectj.lang.JoinPoint;
 4 import org.aspectj.lang.ProceedingJoinPoint;
 5 
 6 public class StudentServiceAspect {
 7 
 8     //前置通知
 9     public void doBefore(JoinPoint jp){
10         System.out.println("类名:"+jp.getTarget().getClass().getName());
11         System.out.println("方法名:"+jp.getSignature().getName());
12         System.out.println("开始添加学生:"+jp.getArgs()[0]);
13     }
14     
15     //后置通知
16     public void doAfter(JoinPoint jp){
17         System.out.println("类名:"+jp.getTarget().getClass().getName());
18         System.out.println("方法名:"+jp.getSignature().getName());
19         System.out.println("学生添加完成:"+jp.getArgs()[0]);
20     }
21     
22     //环绕通知,这里添加了返回值
23     public Object doAround(ProceedingJoinPoint pjp) throws Throwable{
24         System.out.println("添加学生前");
25         Object retVal=pjp.proceed();
26         System.out.println(retVal);
27         System.out.println("添加学生后");
28         return retVal;
29     }
30     
31     //返回通知
32     public void doAfterReturning(JoinPoint jp){
33         System.out.println("返回通知");
34     }
35     
36     //异常通知
37     public void doAfterThrowing(JoinPoint jp,Throwable ex){
38         System.out.println("异常通知");
39         System.out.println("异常信息:"+ex.getMessage());
40     }
41 }

StudentServiceImpl.java:

 1 package com.wishwzp.service.impl;
 2 
 3 import com.wishwzp.service.StudentService;
 4 
 5 public class StudentServiceImpl implements StudentService{
 6 
 7     @Override
 8     public String addStudent(String name) {
 9         // System.out.println("开始添加学生"+name);
10         System.out.println("添加学生"+name);
11         System.out.println(1/0);
12         // System.out.println("完成学生"+name+"的添加");
13         return name;
14     }
15 
16 }

StudentService.java:

1 package com.wishwzp.service;
2 
3 public interface StudentService {
4 
5     public String addStudent(String name);
6 }

 

运行结果显示:

技术分享

 

以上是关于Spring 之AOP 详解的主要内容,如果未能解决你的问题,请参考以下文章

Spring 之AOP 详解

spring之aop详解

Spring AOP之PointCut详解

spring AOP解析之xml方式详解

Spring框架 之IOC容器 和AOP详解

Spring框架系列 - Spring AOP实现原理详解之AOP切面的实现