Spring AOP开发 XML配置和注解配置

1.AOP开发中的相关术语

Joinpoint(连接点):所谓连接点是指那些被拦截到的点。在 spring 中,这些点指的是方法,因为 spring 只
支持方法类型的连接点.
Pointcut(切入点):所谓切入点是指我们要对哪些 Joinpoint 进行拦截的定义.
Advice(通知/增强):所谓通知是指拦截到 Joinpoint 之后所要做的事情就是通知.通知分为前置通知,后置
通知,异常通知,最终通知,环绕通知(切面要完成的功能)
Introduction(引介):引介是一种特殊的通知在不修改类代码的前提下, Introduction 可以在运行期为类
动态地添加一些方法或 Field.
Target(目标对象):代理的目标对象
Weaving(织入):是指把增强应用到目标对象来创建新的代理对象的过程.spring 采用动态代理织入,而 AspectJ 采用编译期织入和类装在期织入

Proxy(代理) :一个类被 AOP 织入增强后,就产生一个结果代理类
Aspect(切面): 是切入点和通知(引介)的结合 

2.Spring 使用 AspectJ 进行 AOP 的开发: XML 的方式

2.1导包

spring-aop-4.2.4.RELEASE.jar com.springsource.org.aopalliance-1.0.0.jar

com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar spring-aspects-4.2.4.RELEASE.jar

Spring AOP开发 XML配置和注解配置_第1张图片

2.2 引入 Spring 的配置文件 : AOP 约束(xml catalog引入约束,xml配置文件中导入命名空间)

2.3编写目标类

package com.lzj.service.Impl;
import com.lzj.service.UserService;
@Service(value="useService")//注意在xml中配置自动beansao'miao
public class UserServiceImpl implements UserService {

	@Override
	public void add() {
		System.out.println("添加记录");
	}

	@Override
	public void delete() {
		System.out.println("删除记录");
	}

	@Override
	public void find() {
		System.out.println("查找记录");
	}

	@Override
	public void update() {
		System.out.println("更新记录");
	}

}

2.4编写通知类

前置通知 :在目标方法执行之前执行.
后置通知 :在目标方法执行之后执行
环绕通知 :在目标方法执行前和执行后执行
异常抛出通知:在目标方法执行出现 异常的时候 执行
最终通知 :无论目标方法是否出现异常 最终通知都会 执行
.

package com.lzj.advice;

import org.aspectj.lang.ProceedingJoinPoint;

public class MyAdvise {
	
	//前置通知
	public void before(){
		System.out.println("前置通知");
	}
	//后置通知
	public void afterReturn(){
		System.out.println("后置通知 (只出现在没有发生异常)");
	}
	
	//环绕通知 常用
	//需要ProceedingJoinPoint接口作为参数 
	public Object around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("环绕通知的之前部分");
		Object proceed = pjp.proceed();
		System.out.println("环绕通知的之后部分");
		return proceed;
	}
	
	//异常抛出通知
	public void afterException(){
		System.out.println("异常出现之后的通知");
	}
	
	//最终通知
	public void after(){
		System.out.println("后置通知(不管是否发生异常)");
	}


}

2.5切入点表达式 execution(表达式)
表达式:
[
方法访问修饰符] 方法返回值 包名.类名.方法名(方法的参数)
public * cn.itcast.spring.dao.*.*(..) //参数任意用..表示
* cn.itcast.spring.dao.*.*(..)
* cn.itcast.spring.dao.*UserDao.*(..)

* cn.itcast.spring.dao..*.*(..)

例如定义切入点表达式 execution (* com.sample.service.impl..*. *(..))
execution()是最常用的切点函数,其语法如下所示:
整个表达式可以分为五个部分:
1、execution(): 表达式主体。
2、第一个*号:表示返回类型, *号表示所有的类型。
3、包名:表示需要拦截的包名,后面的两个句点..表示当前包和当前包的所有子包,com.sample.service.impl包、子孙包下所有类的方法。
4、第二个*号:表示类名,*号表示所有的类。
5、*(..):最后这个星号表示方法名,*号表示所有的方法,后面括弧里面表示方法的参数,两个句点表示任何参数
2.6配置xml完成增强



	
	
	 	 
	 	
		
		
		
		
		
		
			
			
			
			
			
		
	

测试方法

package com.lzj.demo;

import javax.annotation.Resource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.lzj.service.UserService;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class Demo {
	
	@Resource(name="userService")
	private UserService us;
	
	@Test
	public void fun1(){
		us.add();
	}

}

测试结果:

Spring AOP开发 XML配置和注解配置_第2张图片

Spring AOP开发 XML配置和注解配置_第3张图片

3.注解方式配置

非常简单 擦亮你的双眼 !

只需要在通知类中注解写上切入点(PointCut)

第一步 很重要!!!!!!!!!!!!!!!!!!!我第一步忘记做了,足足debug了两个小时 真tm气!暴打梦婷



	

	
	
	

第二步 在通知类中织入

package com.lzj.advice;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Repository;

//声明这是一个切面(切入点+通知)

@Repository(value="myAdvise")
@Aspect
public class MyAdvise {
	
	@Before("execution(* com.lzj.service.*Impl..*.add(..))")
	//前置通知
	public void before(){
		System.out.println("前置通知");
	}
	//后置通知
	@AfterReturning("execution(* com.lzj.service.*Impl..*.add(..))")
	public void afterReturn(){
		System.out.println("后置通知 (只出现在没有发生异常)");
	}
	
	@Around("execution(* com.lzj.service.*Impl..*.add(..))")
	//环绕通知 常用
	//需要ProceedingJoinPoint接口作为参数 
	public Object around(ProceedingJoinPoint pjp) throws Throwable{
		System.out.println("环绕通知的之前部分");
		Object proceed = pjp.proceed();
		System.out.println("环绕通知的之后部分");
		return proceed;
	}
	
	@AfterThrowing("execution(* com.lzj.service.*Impl..*.add(..))")
	//异常抛出通知
	public void afterException(){
		System.out.println("异常出现之后的通知");
	}
	
	@After("execution(* com.lzj.service.*Impl..*.add(..))")
	//最终通知
	public void after(){
		System.out.println("后置通知(不管是否发生异常)");
	}


}



你可能感兴趣的:(Spring AOP开发 XML配置和注解配置)