在实际工作中, 此bean可能是满足业务需要的核心逻辑, 例如test()方法中可能会封装着某个核心业务, 如果在test()方法前后加入日志来跟踪调试, 直接修改源码并不符合面向对象的设计模式, 而随意改动源码也会造成一定的风险。不用怕, Spring为此提供了解决方案。
1.创建用于拦截的bean
1 /** 2 * @filename: AopBean.java 3 * @desc AopBean 测试类 4 * @author: Wang Chinda 5 * @blog http://www.cnblogs.com/goodcheap 6 * @date: 2018-05-25 11:32 7 * @version: v1.0 8 * @copyright: Copyright © 2018 ༄ྂ祸ྂྂ害ོ༘苍ྂྂ生ོ༘࿐ྂ 版权所有 9 * @modify_history: - 10 * 20180525 Wang Chinda create 11 * 20180525 Wang Chinda modify method() 12 */ 13 package com.itdoc.learn.source.aop.demo; 14 15 /** 16 * @desc AopBean 测试类 17 * @author Wang Chinda 18 * @create 2018-05-25 11:32 19 */ 20 public class AopBean { 21 22 public void testMethod() { 23 System.out.println("this is aop test method!"); 24 } 25 }
2.创建Advisor
Spring中摒弃了最原始的繁杂配置方式而采用@Aspect注解对POJO进行标注, 使AOP的工作大大简化, 但是要注意, 使用@Aspect注解需要导入第三方依赖aspectjweaver。
1 /** 2 * @filename: AspectJTest.java 3 * @desc aop切面控制 4 * @author: Wang Chinda 5 * @blog http://www.cnblogs.com/goodcheap 6 * @date: 2018-05-25 11:33 7 * @version: v1.0 8 * @copyright: Copyright © 2018 ༄ྂ祸ྂྂ害ོ༘苍ྂྂ生ོ༘࿐ྂ 版权所有 9 * @modify_history: - 10 * 20180525 Wang Chinda create 11 * 20180525 Wang Chinda modify method() 12 */ 13 package com.itdoc.learn.source.aop.demo; 14 15 16 import org.aspectj.lang.ProceedingJoinPoint; 17 import org.aspectj.lang.annotation.*; 18 19 /** 20 * @desc aop切面控制, 创建Advisor 21 * @author Wang Chinda 22 * @create 2018-05-25 11:33 23 */ 24 @Aspect 25 public class AspectJTest { 26 27 @Pointcut("execution(* *.*(..))") 28 public void test() { 29 } 30 31 @Before("test()") 32 public void beforeTest() { 33 System.out.println("beforeTest"); 34 } 35 36 @After("test()") 37 public void afterTest() { 38 System.out.println("afterTest"); 39 } 40 41 @Around("test()") 42 public Object aroundTest(ProceedingJoinPoint point) { 43 Object obj = null; 44 try { 45 System.out.println("前置通知"); 46 obj = point.proceed(); 47 System.out.println("返回通知"); 48 } catch (Throwable throwable) { 49 throwable.printStackTrace(); 50 System.out.println("异常通知"); 51 } finally { 52 System.out.println("后置通知"); 53 } 54 return obj; 55 } 56 57 }
3.引入第三方依赖:
1 <?xml version="1.0" encoding="UTF-8"?> 2 3 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 5 <modelVersion>4.0.0</modelVersion> 6 7 <groupId>com.itdoc.learn.source</groupId> 8 <artifactId>spring-01</artifactId> 9 <version>1.0-SNAPSHOT</version> 10 11 <name>spring-01</name> 12 13 14 <properties> 15 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 16 <maven.compiler.source>1.7</maven.compiler.source> 17 <maven.compiler.target>1.7</maven.compiler.target> 18 </properties> 19 20 <dependencies> 21 22 <!-- https://mvnrepository.com/artifact/org.springframework/spring-web --> 23 <dependency> 24 <groupId>org.springframework</groupId> 25 <artifactId>spring-web</artifactId> 26 <version>3.2.3.RELEASE</version> 27 </dependency> 28 29 <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 --> 30 <dependency> 31 <groupId>org.apache.commons</groupId> 32 <artifactId>commons-lang3</artifactId> 33 <version>3.4</version> 34 </dependency> 35 36 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver --> 37 <!-- aop功能 @Aspect 注解依赖包 --> 38 <dependency> 39 <groupId>org.aspectj</groupId> 40 <artifactId>aspectjweaver</artifactId> 41 <version>1.8.10</version> 42 </dependency> 43 44 <!-- https://mvnrepository.com/artifact/aopalliance/aopalliance --> 45 <!--<dependency>--> 46 <!--<groupId>aopalliance</groupId>--> 47 <!--<artifactId>aopalliance</artifactId>--> 48 <!--<version>1.0</version>--> 49 <!--</dependency>--> 50 51 52 <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjrt --> 53 <!--<dependency>--> 54 <!--<groupId>org.aspectj</groupId>--> 55 <!--<artifactId>aspectjrt</artifactId>--> 56 <!--<version>1.8.9</version>--> 57 <!--</dependency>--> 58 59 60 61 <!-- https://mvnrepository.com/artifact/javax.inject/javax.inject --> 62 <dependency> 63 <groupId>javax.inject</groupId> 64 <artifactId>javax.inject</artifactId> 65 <version>1</version> 66 </dependency> 67 68 <dependency> 69 <groupId>junit</groupId> 70 <artifactId>junit</artifactId> 71 <version>RELEASE</version> 72 </dependency> 73 </dependencies> 74 75 <build> 76 <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) --> 77 <plugins> 78 <plugin> 79 <artifactId>maven-clean-plugin</artifactId> 80 <version>3.0.0</version> 81 </plugin> 82 <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_jar_packaging --> 83 <plugin> 84 <artifactId>maven-resources-plugin</artifactId> 85 <version>3.0.2</version> 86 </plugin> 87 <plugin> 88 <artifactId>maven-compiler-plugin</artifactId> 89 <version>3.7.0</version> 90 </plugin> 91 <plugin> 92 <artifactId>maven-surefire-plugin</artifactId> 93 <version>2.20.1</version> 94 </plugin> 95 <plugin> 96 <artifactId>maven-jar-plugin</artifactId> 97 <version>3.0.2</version> 98 </plugin> 99 <plugin> 100 <artifactId>maven-install-plugin</artifactId> 101 <version>2.5.2</version> 102 </plugin> 103 <plugin> 104 <artifactId>maven-deploy-plugin</artifactId> 105 <version>2.8.2</version> 106 </plugin> 107 </plugins> 108 </pluginManagement> 109 </build> 110 </project>
4.配置aop:在xml中开启aop功能
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 http://www.springframework.org/schema/beans/spring-beans.xsd 6 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> 7 8 <!-- 使 AspectJ 注解起作用, 自动为匹配的类生成代理对象 --> 9 <aop:aspectj-autoproxy/> 10 11 <bean id="test" class="com.itdoc.learn.source.aop.demo.AopBean"/> 12 <bean class="com.itdoc.learn.source.aop.demo.AspectJTest"/> 13 </beans>
5.测试
1 /** 2 * @filename: AopDemoClient.java 3 * @desc 4 * @author: Wang Chinda 5 * @blog http://www.cnblogs.com/goodcheap 6 * @date: 2018-05-25 12:00 7 * @version: v1.0 8 * @copyright: Copyright © 2018 ༄ྂ祸ྂྂ害ོ༘苍ྂྂ生ོ༘࿐ྂ 版权所有 9 * @modify_history: - 10 * 20180525 Wang Chinda create 11 * 20180525 Wang Chinda modify method() 12 */ 13 package com.itdoc.learn.source.aop.demo; 14 15 import org.springframework.context.ApplicationContext; 16 import org.springframework.context.support.ClassPathXmlApplicationContext; 17 18 /** 19 * @desc 20 * @author Wang Chinda 21 * @create 2018-05-25 12:00 22 */ 23 public class AopDemoClient { 24 public static void main(String[] args) { 25 ApplicationContext app = new ClassPathXmlApplicationContext("test/aopDemo.xml"); 26 AopBean aopBean = (AopBean) app.getBean("test"); 27 aopBean.testMethod(); 28 } 29 }
控制台输出:
五月 25, 2018 3:07:21 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh 信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@1e67b872: startup date [Fri May 25 15:07:21 CST 2018]; root of context hierarchy 五月 25, 2018 3:07:21 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions 信息: Loading XML bean definitions from class path resource [test/aopDemo.xml] 五月 25, 2018 3:07:22 下午 org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons 信息: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@5c30a9b0: defining beans [org.springframework.aop.config.internalAutoProxyCreator,test,com.itdoc.learn.source.aop.demo.AspectJTest#0]; root of factory hierarchy 前置通知 beforeTest this is aop test method! 返回通知 后置通知 afterTest
GitHub源码:https://github.com/wcd19901010/spring-01