1.AOP到底是什么?

Aspect Oriented Programing 面向切面编程

 

 

 

 

 

 

1.2.3.4代码不重复 不能向上抽取 不能纵向抽取

但是横向却可以抽取 将 业务和 监视事务分离

 

连接点(Joinpoint):连接点相当于方法,相当于数据库里的记录

切点(Pointcut):相当于数据库里的查询条件,一个切点对应多个连接点

增强(Advice):是织入目标类连接点上的一段代码,描述信息

目标对象(Target):增强织入的逻辑类引介(Introduction):特殊的增强,属性和方法

织人:是将增强添加到目标类具体连接点上的过程,

代理类(Proxy):AOP织入增强后,产生一个结果类它是融入原类和增强逻辑的代理类

切面(Aspect):切面是由切点和引介组成 ,将横切逻辑织入切面所指定的连接点

 

 

1.创建增强类

通过实现接口,在接口方法中定义横切逻辑,就可以将它们织人目标方法的相应连接点的位置

1.1 前置增强

1 package com.asm;
2 
3 public interface Waiter {
4     void greetTo(String name);
5 
6     void serveTo(String name);
7 }

 

 1 public class NaiveWaiter implements Waiter {
 2 
 3     public void greetTo(String name) {
 4         System.out.println("greet to " + name + "...");
 5     }
 6 
 7     public void serveTo(String name) {
 8         System.out.println("serving " + name + "...");
 9     }
10 }

 

 1 public class GreetingBeforeAdvice implements MethodBeforeAdvice{
 2 
 3     @Override
 4     public void before(Method method, Object[] args, Object obj)
 5             throws Throwable {
 6          String clientName=(String)args[0];
 7          System.out.println("How are you mr,"+clientName+".");
 8     }
 9 
10     
11 }

 

 

 1 package com.asm;
 2 
 3 import org.springframework.aop.BeforeAdvice;
 4 import org.springframework.aop.framework.ProxyFactory;
 5 import org.testng.annotations.BeforeTest;
 6 import org.testng.annotations.Test;
 7 
 8 public class BeforeAdviceTest {
 9 
10     private Waiter target;
11     private BeforeAdvice advice;
12     private ProxyFactory pf;
13 
14     @BeforeTest
15     public void init() {
16         target = new NaiveWaiter();
17         advice = new GreetingBeforeAdvice();
18         //①Spring提供的代理工厂
19         pf = new ProxyFactory();
20         // ②设置代理目标
21         pf.setTarget(target);
22         //③为代理目标添加增强
23         pf.addAdvice(advice);
24     }
25 
26     @Test
27     public void beforeAdvice() {
28         Waiter proxy = (Waiter) pf.getProxy();
29         proxy.greetTo("John");
30         proxy.serveTo("Tom");
31     }
32 }

 

 

在Spring配置增强

 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" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 8        http://www.springframework.org/schema/context 
 9        http://www.springframework.org/schema/context/spring-context-3.1.xsd
10        http://www.springframework.org/schema/tx 
11        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
12        http://www.springframework.org/schema/aop
13        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
14        
15        <!-- 扫描类包下的类 这样Spring定义的注解才能产生作用
16            如@Resposity @Autowired
17         -->
18        
19        <!-- 需要代理的业务类 -->  
20     <bean id="target" class="com.asm.NaiveWaiter"></bean>  
21     <!-- 指定增强,一个业务类可以有多个增强形成增强链,调用顺序与添加顺序一致 -->  
22     <bean id="greetAdvice" class="com.asm.GreetingBeforeAdvice"></bean>  
23     <!-- 利用ProxyFactoryBean创建代理 -->  
24     <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"
25     p:proxyInterfaces="com.asm.Waiter" // 指定代理接口,多个用List
26     p:interceptorNames="greetAdvice"   //指定增强
27     p:target-ref="target"     //指定对哪个bean进行代理
28     />  
29  </beans>

 

 1 package com.asm;
 2 
 3 import org.springframework.context.ApplicationContext;
 4 import org.springframework.context.support.ClassPathXmlApplicationContext;
 5 import org.testng.annotations.Test;
 6 
 7 public class SpringTest1 {
 8     
 9     public static void main(String[] args) {
10         
11         ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
12         Waiter waiter = (Waiter) ctx.getBean("waiter");
13         waiter.greetTo("join");
14     }
15 }

 

 

后置增强:

1 public class GreetingAfterAdvice implements AfterReturningAdvice {
2 
3     public void afterReturning(Object returnObj, Method method, Object[] args,
4                                Object obj) throws Throwable {
5         System.out.println("Please enjoy yourself!");
6     }
7 }

 

 

 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" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 8        http://www.springframework.org/schema/context 
 9        http://www.springframework.org/schema/context/spring-context-3.1.xsd
10        http://www.springframework.org/schema/tx 
11        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
12        http://www.springframework.org/schema/aop
13        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
14        
15        <!-- 扫描类包下的类 这样Spring定义的注解才能产生作用
16            如@Resposity @Autowired
17         -->
18        
19        <!-- 需要代理的业务类 -->  
20     <bean id="target" class="com.asm.NaiveWaiter"></bean>  
21     <!-- 指定增强,一个业务类可以有多个增强形成增强链,调用顺序与添加顺序一致 -->  
22     <bean id="greetBefore" class="com.asm.GreetingBeforeAdvice">
23 </bean> 
24 <bean id="greetAfter" class="com.asm.GreetingAfterAdvice">
25 </bean> 
26     <!-- 利用ProxyFactoryBean创建代理 -->  
27     <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"
28     p:proxyInterfaces="com.asm.Waiter"
29     p:interceptorNames="greetBefore,greetingAfter"
30     p:target-ref="target"
31     />  
32  </beans>

 

 

环绕增强:

 1 package com.smart.advice;
 2 
 3 import org.aopalliance.intercept.MethodInterceptor;
 4 import org.aopalliance.intercept.MethodInvocation;
 5 
 6 public class GreetingInterceptor implements MethodInterceptor {
 7 
 8     public Object invoke(MethodInvocation invocation) throws Throwable {
 9         Object[] args = invocation.getArguments();
10         String clientName = (String) args[0];
11         System.out.println("How are you!Mr." + clientName + ".");
12 
13         Object obj = invocation.proceed();
14 
15         System.out.println("Please enjoy yourself!");
16 
17         return obj;
18     }
19 }

 

 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" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 8        http://www.springframework.org/schema/context 
 9        http://www.springframework.org/schema/context/spring-context-3.1.xsd
10        http://www.springframework.org/schema/tx 
11        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
12        http://www.springframework.org/schema/aop
13        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
14        
15        <!-- 扫描类包下的类 这样Spring定义的注解才能产生作用
16            如@Resposity @Autowired
17         -->
18        
19        <!-- 需要代理的业务类 -->  
20     <bean id="target" class="com.asm.NaiveWaiter"></bean>  
21     <!-- 指定增强,一个业务类可以有多个增强形成增强链,调用顺序与添加顺序一致 -->  
22     <bean id="greetAdvice" class="com.asm.GreetingInterceptor "></bean>  
23     <!-- 利用ProxyFactoryBean创建代理 -->  
24     <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"
25     p:proxyInterfaces="com.asm.Waiter"
26     p:interceptorNames="greetAdvice"
27     p:target-ref="target"
28     />  
29  </beans>

 

 

异常增强:

 1 public class TransactionManager implements ThrowsAdvice {
 2 
 3 
 4     public void afterThrowing(Method method, Object[] args, Object target,
 5                               Exception ex) throws Throwable {
 6         ex = null;
 7         System.out.println("-----------");
 8         System.out.println("method:" + method.getName());
 9         //System.out.println("抛出异常:" + ex.getMessage());
10         System.out.println("成功回滚事务。");
11     }
12 }

 

 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" xmlns:p="http://www.springframework.org/schema/p"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
 6     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 7        http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
 8        http://www.springframework.org/schema/context 
 9        http://www.springframework.org/schema/context/spring-context-3.1.xsd
10        http://www.springframework.org/schema/tx 
11        http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
12        http://www.springframework.org/schema/aop
13        http://www.springframework.org/schema/aop/spring-aop-3.1.xsd">
14        
15        <!-- 扫描类包下的类 这样Spring定义的注解才能产生作用
16            如@Resposity @Autowired
17         -->
18        
19        <!-- 需要代理的业务类 -->  
20     <bean id="target" class="com.asm.NaiveWaiter"></bean>  
21     <!-- 指定增强,一个业务类可以有多个增强形成增强链,调用顺序与添加顺序一致 -->  
22     <bean id="transactionManager" class="com.asm.TransactionManager "></bean>  
23     <!-- 利用ProxyFactoryBean创建代理 -->  
24     <bean id="waiter" class="org.springframework.aop.framework.ProxyFactoryBean"
25     p:proxyInterfaces="com.asm.Waiter"
26     p:interceptorNames="greetAdvice"
27     p:target-ref="target"
28     p:proxyTargetClass="true" //CGLIB代理
29     />  
30  </beans>

 

 

 

 

spring目前支持5种类型增强:

  • 前置增强:org.springframework.aop.BeforeAdvice 代表前置增强,因为spring只支持方法级的增强,所以MethodBeforeAdvice是目前可用的前置增强,表示在目标方法执行前实施增强,而 BeforeAdvice是为了将来版本扩展需要而定义的。

  • 后置增强:org.springframework.aop.AfterReturningAdvice代表后增强,表示在目标方法执行后实施增强。

  • 环绕增强:org.aopalliance.intercept.MethodInterceptor代表环绕增强,表示在目标方法执行前后实施增强。

  • 异常抛出增强:org.springframework.aop.ThrowsAdvice代表抛出异常增强,表示在目标方法抛出异常后实施增强。

  • 引介增强:org.springframework.aop.IntroductionInterceptor代表引介增强,表示在目标类中添加一些新的方法和属性。

posted on 2016-06-18 23:55  Sharpest  阅读(269)  评论(0)    收藏  举报