深入理解springAOP
概念:AOP(Aspect-Oriented Programming)即面向切面编程。它是对传统的OOP(面向对象)编程的一种补充,在OOP中往往一个对象有什么行为我们就定义什么方法,对象与对象之间存在紧密联系。与OOP不同的是AOP更加关注的是切面,我们只需要关注于对象的核心业务而不是所有的业务。
如同上图1中所示,两个螺丝就是一种紧密耦合的关系, 一旦一方存在问题,另一方也必须做出相应调整。而图2为一个笔记本的USB插口,只要符合这个接口的设备都可以使用这个插口。
在程序中也和现实生活一样,使用spring AOP就是一种典型的非耦合案例,AOP的核心之一就是我们的非核心业务与我们的核心业务解耦。
具体实现:(本例我们模拟一个女孩子的日常生活,去KFC,约会,遛狗几个事务)
第一步:既然是使用spring自然要配置相关环境,然后直接写我们的核心业务,而在一个程序中我们在多个流程中反复出现的一些非核心代码抽取出来由代理给我们管理。我们发现这几个事务之前我们的对象(女孩子)都要洗澡,化妆......之后都要卸妆....这些非逻辑业务便是我们需要分离出来的。
1 package aop_demo; 2 3 /* 4 * 5 */ 6 public class Girl1 implements Girl{ 7 8 private Dog dog = null; 9 10 public void setDog(Dog dog) { 11 this.dog = dog; 12 } 13 14 public void KFC(String datetime){ 15 16 System.out.println("[核心业务逻辑]我是第一个女孩"); 17 System.out.println("[核心业务逻辑]"+datetime+"吃肯德基"); 18 } 19 20 public void meet(String datetime){ 21 22 System.out.println("[核心业务逻辑]我是第一个女孩"); 23 System.out.println("[核心业务逻辑]"+datetime+"约会"); 24 25 } 26 27 29 @Override 30 public void playDog() { 31 32 dog.bark(); 33 34 } 35 36 }
本例中的对象还一个dog属性因此我们还一个dog对象以及它的方法
1 package aop_demo; 2 3 public class Dog_taidi implements Dog { 4 5 @Override 6 public void bark() { 7 System.out.println("旺旺,我是泰迪"); 8 } 9 10 }
第二步,统一管理我们的非核心业务也就是代理了。
上图中的通知其本质也就是代理,由于本例中前后都有非核心业务,因此我们选择环绕通知
1 package aop_demo; 2 3 import org.aopalliance.intercept.MethodInterceptor; 4 import org.aopalliance.intercept.MethodInvocation; 5 6 7 public class AroundAdvice implements MethodInterceptor { 8 9 @Override 10 public Object invoke(MethodInvocation invocation) throws Throwable { 11 12 //前置业务 13 System.out.println("[代理执行前置]洗澡"); 14 System.out.println("[代理执行前置]化妆"); 15 System.out.println("[代理执行前置]穿衣服"); 16 System.out.println("*****************"); 17 18 //核心业务 19 Object result = invocation.proceed(); 20 21 //后置业务 22 System.out.println("*****************"); 23 System.out.println("[代理执行后置]卸妆"); 24 System.out.println("[代理执行后置]洗澡"); 25 System.out.println("[代理执行后置]听歌"); 26 System.out.println(""); 27 28 return result; 29 } 30 31 32 }
第三步,配置applicationContext.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:p="http://www.springframework.org/schema/p" 5 xmlns:aop="http://www.springframework.org/schema/aop" 6 xmlns:context="http://www.springframework.org/schema/context" 7 xmlns:jee="http://www.springframework.org/schema/jee" 8 xmlns:tx="http://www.springframework.org/schema/tx" 9 xsi:schemaLocation=" 10 http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 11 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 12 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd 13 http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd 14 http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> 15 16 <bean id="girl" class="aop_demo.Girl1" scope="prototype"> 17 <!-- g1.setDog(dog1); --> 18 <property name="dog" ref="dog1"></property> 19 </bean> 20 21 <!-- Dog dog1 = new Dog_taidi(); --> 22 <bean id="dog1" class="aop_demo.Dog_taidi" scope="prototype"> 23 24 </bean> 25 26 <bean id="girlHandler" class="aop_demo.GirlHandler" scope="prototype"> 27 <property name="target" ref="girl"></property> 28 </bean> 29 30 <bean id="aroundAdvice" class="aop_demo.AroundAdvice"></bean> 31 32 <bean id="girlProxy" class="org.springframework.aop.framework.ProxyFactoryBean" scope="prototype"> 33 <property name="interceptorNames" value="aroundAdvice"></property> 34 <property name="target" ref="girl"></property> 35 </bean> 36 37 38 </beans>
第四步,构造我们的测试程序
1 package aop_demo; 2 3 import org.springframework.context.ApplicationContext; 4 import org.springframework.context.support.FileSystemXmlApplicationContext; 5 6 public class Test { 7 8 public static void main(String[] args) { 9 10 ApplicationContext context = new FileSystemXmlApplicationContext("applicationContext.xml"); 11 12 Girl g1 = (Girl)context.getBean("girlProxy"); 13 14 System.out.println(""); 15 System.out.println(""); 16 System.out.println(""); 17 System.out.println(""); 18 19 g1.KFC("周日"); 20 g1.meet("周六"); 21 //开始遛狗 22 g1.playDog(); 23 24 } 25 26 }