Spring AOP 的实现

Posted 走在一线的码农

tags:

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

软件152 余建强

1 使用 API 实现 AOP

新建一个用户接口:UserService

1 package com.cqvie.aop.api;
2 
3 public interface UserService {
4 
5     public void add(String name);
6     public void update(String name);
7     public void delete(String name);
8     public void select(String name);
9 }

实现接口类:UserServiceImpl

 1 package com.cqvie.aop.api;
 2 
 3 public class UserServiceImpl implements UserService {
 4 
 5     @Override
 6     public void add(String name) {
 7         System.out.println("Add User " + name + " SUCCESS!");
 8     }
 9 
10     @Override
11     public void update(String name) {
12         System.out.println("Update User " + name + " SUCCESS!");
13     }
14 
15     @Override
16     public void delete(String name) {
17         System.out.println("Delete User " + name + " SUCCESS!");
18     }
19 
20     @Override
21     public void select(String name) {
22         System.out.println("Select User " + name + " SUCCESS!");
23     }
24 
25 }

写一个日志类,包括前置通知和后置通知:Log

 1 package com.cqvie.aop.api;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.springframework.aop.AfterReturningAdvice;
 6 import org.springframework.aop.MethodBeforeAdvice;
 7 
 8 public class Log implements MethodBeforeAdvice, AfterReturningAdvice {
 9 
10     /**
11      * 前置通知
12      * @param method 被调用方法对象
13      * @param args 被调用的方法参数
14      * @param target 被调用的方法的目标对象
15      */
16     @Override
17     public void before(Method method, Object[] args, Object target) throws Throwable {
18         System.out.println(target.getClass().getName() + " 的 " + 
19                 method.getName() + "方法被执行···");
20     }
21 
22     /**
23      * 后置通知
24      * @param returnValue 返回值
25      * @param method 被调用的方法对象
26      * @param args 被调用的方法对象的参数
27      * @param target 被调用的方法对象的目标对象
28      */
29     @Override
30     public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
31         System.out.println(target.getClass().getName() + " 的 " + 
32                 method.getName() + "方法已成功执行!返回值为:" + returnValue);
33         System.out.println();
34     }
35 }

配置 Spring 的配置文件:applicationContext01.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:context="http://www.springframework.org/schema/context"
 5      xmlns:aop="http://www.springframework.org/schema/aop"
 6      xsi:schemaLocation="http://www.springframework.org/schema/beans
 7          http://www.springframework.org/schema/beans/spring-beans.xsd
 8          http://www.springframework.org/schema/context
 9          http://www.springframework.org/schema/context/spring-context.xsd
10          http://www.springframework.org/schema/aop 
11          http://www.springframework.org/schema/aop/spring-aop.xsd">
12          
13     <bean id="userService" class="com.cqvie.aop.api.UserServiceImpl"></bean>
14     <bean id="log" class="com.cqvie.aop.api.Log"></bean>
15     <aop:config>
16         <aop:pointcut expression="execution(* com.cqvie.aop.api.UserServiceImpl.*(..))" id="pointcut"/>
17         <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
18     </aop:config>
19     
20 </beans>

添加一个测试类:Test

 1 package com.cqvie.aop.api;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class Test {
 7 
 8     public static void main(String[] args) {
 9         
10         @SuppressWarnings("resource")
11         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext01.xml");
12         UserService userService = (UserService) ac.getBean("userService");
13         userService.update("AngeYu");
14         userService.delete("AngeYu");
15         
16     }
17 
18 }

运行结果:

 

2 自定义类实现 AOP

接口和接口的实现类不变,依旧是上面所提到的 UserService 和 UserServiceIpml

自己写一个日志类 Log,包含前置通知和后置通知

 1 package com.cqvie.aop.custom;
 2 
 3 public class Log {
 4 
 5     public void before() {
 6         System.out.println("----- method start -----");
 7     }
 8     
 9     public void after() {
10         System.out.println("----- method end -----");
11     }
12     
13 }

配置 Spring 的配置文件:applicationContext02.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:context="http://www.springframework.org/schema/context"
 5      xmlns:aop="http://www.springframework.org/schema/aop"
 6      xsi:schemaLocation="http://www.springframework.org/schema/beans
 7          http://www.springframework.org/schema/beans/spring-beans.xsd
 8          http://www.springframework.org/schema/context
 9          http://www.springframework.org/schema/context/spring-context.xsd
10          http://www.springframework.org/schema/aop 
11          http://www.springframework.org/schema/aop/spring-aop.xsd">
12          
13     <bean id="userService" class="com.cqvie.aop.custom.UserServiceImpl"></bean>
14     <bean id="log" class="com.cqvie.aop.custom.Log"></bean>
15     <aop:config>
16         <aop:aspect ref="log">
17             <aop:pointcut expression="execution(* com.cqvie.aop.custom.UserServiceImpl.*(..))" id="pointcut"/>
18             <aop:before method="before" pointcut-ref="pointcut"/>
19             <aop:after method="after" pointcut-ref="pointcut"/>
20         </aop:aspect>
21     </aop:config>
22     
23 </beans>

添加一个测试类:Test

 1 package com.cqvie.aop.custom;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class Test {
 7 
 8     public static void main(String[] args) {
 9         
10         @SuppressWarnings("resource")
11         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext02.xml");
12         UserService userService = (UserService) ac.getBean("userService");
13         userService.update("AngeYu");
14         
15     }
16 
17 }

运行结果:

 

3 使用注解实现 AOP

接口和接口的实现类不变,依旧是上面所提到的 UserService 和 UserServiceIpml

自己写一个日志类 Log,包含前置通知、后置通知、环绕通知

 1 package com.cqvie.aop.annotation;
 2 
 3 import org.aspectj.lang.ProceedingJoinPoint;
 4 import org.aspectj.lang.annotation.After;
 5 import org.aspectj.lang.annotation.Around;
 6 import org.aspectj.lang.annotation.Aspect;
 7 import org.aspectj.lang.annotation.Before;
 8 
 9 @Aspect
10 public class Log {
11 
12     @Before("execution(* com.cqvie.aop.annotation.UserServiceImpl.*(..))")
13     public void before() {
14         System.out.println("----- method start -----");
15     }
16     
17     @After("execution(* com.cqvie.aop.annotation.UserServiceImpl.*(..))")
18     public void after() {
19         System.out.println("----- method end -----");
20     }
21     
22     @Around("execution(* com.cqvie.aop.annotation.UserServiceImpl.*(..))")
23     public Object around(ProceedingJoinPoint pj) throws Throwable {
24         System.out.println("--- around start ---");
25         System.out.println("方法签名:" + pj.getSignature());
26         Object result = pj.proceed();
27         System.out.println("--- around end ---");
28         return result;
29     }
30     
31 }

配置 Spring 的配置文件:applicationContext03.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:context="http://www.springframework.org/schema/context"
 5      xmlns:aop="http://www.springframework.org/schema/aop"
 6      xsi:schemaLocation="http://www.springframework.org/schema/beans
 7          http://www.springframework.org/schema/beans/spring-beans.xsd
 8          http://www.springframework.org/schema/context
 9          http://www.springframework.org/schema/context/spring-context.xsd
10          http://www.springframework.org/schema/aop 
11          http://www.springframework.org/schema/aop/spring-aop.xsd">
12          
13     <bean id="userService" class="com.cqvie.aop.annotation.UserServiceImpl"></bean>
14     <bean id="log" class="com.cqvie.aop.annotation.Log"></bean>
15     <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
16     
17 </beans>

添加一个测试类:Test

 1 package com.cqvie.aop.annotation;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 
 6 public class Test {
 7 
 8     public static void main(String[] args) {
 9         
10         @SuppressWarnings("resource")
11         ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext03.xml");
12         UserService userService = (UserService) ac.getBean("userService");
13         userService.update("AngeYu");
14         
15     }
16 
17 }

运行结果:

 

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

spring aop配置及实现

Spring AOP 应用:三种配置及实现方式

使用Spring配置文件实现AOP

JAVA之AOP

spring-AOP原理

Spring_AOP的实现机制-动态代理