论坛首页 Java企业应用论坛

Spring之AOP学习小结

浏览 14258 次
精华帖 (3) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2009-10-14  
在学习aop之前先来解释一下aop一些概念
  • Joinpoint:它定义在哪里加入你的逻辑功能,对于Spring AOP,Jointpoint指的就是Method。
  • Advice:特定的Jointpoint处运行的代码,对于Spring AOP 来讲,有Before advice、AfterreturningAdvice、ThrowAdvice、AroundAdvice(MethodInteceptor)等。
  • Pointcut:一组Joinpoint,就是说一个Advice可能在多个地方织入,
  • Aspect:实际是Advice和Pointcut的组合,但是Spring AOP 中的Advisor也是这样一个东西,但是Spring中为什么叫Advisor而不叫做Aspect。
  • Target:被通知的对象。
  • Proxy:将通知应用到目标对象后创建的对象
  • Weaving:将Aspect加入到程序代码的过程,对于Spring AOP,由ProxyFactory或者ProxyFactoryBean负责织入动作。


spring对AOP的支持有以下4种情况:
  • 经典的基于代理的aop(各版本spring)
  • @AspectJ注解驱动的切面(spring2.0后)
  • 纯pojo切面(spring2.0后)
  • 注入式AspectJ切面(各版本spring)


ITarget.java
package com.myspring.aop;

public interface ITarget {
  public void execute() throws TargetException;
}


TargetImpl.java
package com.myspring.aop;

public class TargetImpl implements ITarget {
  
  public TargetImpl() {
  }
   
  public void execute() throws TargetException {
    System.out.println("main...");
  }
}


创建通知
Advice .java
package com.myspring.aop;

import java.lang.reflect.Method;

import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;

public class Advice implements MethodBeforeAdvice,
    AfterReturningAdvice, ThrowsAdvice {

  public Advice() {}
    
  public void before(Method method, Object[] args, Object target) 
      throws Throwable {
    System.out.println("传统经典aop的before...");
  }
  
  public void afterReturning(Object rtn, Method method, 
      Object[] args, Object target) throws Throwable {
    System.out.println("传统经典aop的afterReturning...");
  }
  
  public void afterThrowing(Throwable throwable) {
    System.out.println("传统经典aop的afterThrowing...");
  }
  
  public void afterThrowing(Method method, Object[] args, Object target, 
      Throwable throwable) {
	  System.out.println("传统经典aop的afterThrowing2...");
  }
  
}


TargetException .java
package com.myspring.aop;

@SuppressWarnings("serial")
public class TargetException extends RuntimeException {
  public TargetException() {}
  
  public TargetException(String message) {
    super(message);
  }
}


使用自动代理@AspectJ切面时,需要先注册一个切面AspectAdvice.java
package com.myspring.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;

@Aspect//声明切面
public class AspectAdvice {
	
	@Pointcut("execution(* *.execute(..))")//定义切点,匹配规则为(返回类型 返回类.方法(参数设置)
	public void todo(){}
	
	@Before("todo()")
	public void before() {
		System.out.println("自动代理@AspectJ切面before...");
	}
	
	@AfterReturning("todo()")
	public void afterReturning() {
		System.out.println("自动代理@AspectJ切面afterReturning...");
	}
	
	@AfterThrowing("todo()")
	public void afterThrowing() {
		System.out.println("自动代理@AspectJ切面afterThrowing...");
	}

}

AdviceBean.java
package com.myspring.aop;

public class AdviceBean {
	
	public void before() {
		System.out.println("纯POJO切面before...");
	}
	
	public void afterReturning() {
		System.out.println("纯POJO切面afterReturning...");
	}
	
	public void afterThrowing() {
		System.out.println("纯POJO切面afterThrowing...");
	}
}



applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:p="http://www.springframework.org/schema/p"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
	http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
	
	<!-- 当定义一个纯粹的POJO切面时,创建此Bean -->
	<bean id="adviceBean" class="com.myspring.aop.AdviceBean"></bean>
	<!-- 利用spring AOP的配置元素定义一个通知 -->
	<aop:config> 
		<!-- 引用刚才定义的一个纯粹的POJO切面Bean -->
		<aop:aspect ref="adviceBean">
		<!-- 定义一个命名切点,必点切点定义的重复,expression用于配置匹配规则,(返回类型 返回类.方法(参数设置) -->
		<aop:pointcut id="todo" expression="execution(* com.myspring.aop.TargetImpl.execute(..))" />	
		<!-- 方法前通知 -->	 	
		<aop:before method="before" pointcut-ref="todo" />		
		<aop:after-returning method="afterReturning" pointcut-ref="todo" />	
		<aop:after-throwing method="afterThrowing" pointcut-ref="todo"/>
    </aop:aspect>
  </aop:config>	

	<!-- ************************************** -->
	<bean id="aspectAdvice" class="com.myspring.aop.AspectAdvice"></bean>
	<!-- 当使用自动代理@AspectJ切面时,需要定义自动配置元素,在原来的xml文件的beans中加入xmlns:aop="http://www.springframework.org/schema/aop" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd,具体位置如上 -->
	<aop:aspectj-autoprox />

	<!-- ************************************** -->	
	<!-- 以下为传统的aop代理 -->
	<!-- 定义一个bean -->
	<bean id="target" class="com.myspring.aop.TargetImpl">
	</bean>

	<!-- 定义一个通知bean -->
	<bean id="advice" class="com.myspring.aop.Advice">
	</bean>
	
	<!-- 正则表达式切入点 -->
	<bean id="jdkRegexpAdvisor"		class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
		<property name="advice" ref="advice" />
		<property name="pattern" value=".*execute" />
	</bean>
	
	<!-- AspectJ切点 -->
	<bean id="aspectjPointcut" class="org.springframework.aop.aspectj.AspectJExpressionPointcutAdvisor">
		<property name="advice" ref="advice" /> <property name="expression"
		value="execution(* *.execute(..))" /> </bean>	
	<!-- 使用ProxyFactoryBean工厂,用于生成一个代理,把一个或多个拦截者(和通知者)应用到Bean -->
	<bean id="myAop" class="org.springframework.aop.framework.ProxyFactoryBean">
		<property name="target" ref="target" />
		<property name="proxyInterfaces" value="com.myspring.aop.ITarget" />
		<property name="interceptorNames" value="jdkRegexpAdvisor" />
	</bean>
	
	<!-- 创建自动代理,会自动检查通知者的切点是否匹配bean的方法,并且使用通知的代理来替换这个bean定义 -->
	<bean
		class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator" />
</beans>


TestSpringAop.java
package com.myspring.aop;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestSpringAop {
  public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
    //使用经典的aop
    ITarget target = (ITarget) ctx.getBean("myAop");
    //使用自动代理,可以直接调用目标对象
    ITarget autotarget = (ITarget) ctx.getBean("target");
    target.execute();
  }
}
   发表时间:2009-10-15  
总结的有点少.
0 请登录后投票
   发表时间:2009-10-16  
spring AOP入门贴,其实spring的中文参考手册上写的更清楚
0 请登录后投票
   发表时间:2009-10-17  
确实是入门级别的文章。。。不过还是得表扬
0 请登录后投票
   发表时间:2009-10-18  
YiSingQ 写道
确实是入门级别的文章。。。不过还是得表扬





行家看行道,外行看热闹。
老手看代码,新看看全解。

收下了,,
1 请登录后投票
   发表时间:2010-08-03  
对于我这初学人员还是很有帮助,多谢分享。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics