spring的AOP(五)----Spring AOP 编程(AspectJ )

AspectJ 简介
AspectJ是一个面向切面的框架,它扩展了Java语言。AspectJ定义了AOP语法所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件。
AspectJ是一个基于Java语言的AOP框架
Spring2.0以后新增了对AspectJ切点表达式支持
@AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
新版本Spring框架,建议使用AspectJ方式来开发AOP
使用AspectJ 需要导入Spring AOP和 AspectJ相关jar包
spring-aop-3.2.0.RELEASE.jar
com.springsource.org.aopalliance-1.0.0.jar
spring-aspects-3.2.0.RELEASE.jar
com.springsource.org.aspectj.weaver-1.6.8.RELEASE.jar

在配置文件中,引入 aop 的schema约束

<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"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	
</beans>

AspectJ 框架定义 Advice 增强类型 (六种 )
AspectJ 在传统AOP 的advice类型基础上,扩展了一种新的类型
1.Before 前置通知,相当于BeforeAdvice
2.AfterReturning 后置通知,相当于AfterReturningAdvice
3.Around 环绕通知,相当于MethodInterceptor
4.AfterThrowing 抛出通知,相当于ThrowAdvice
5.After 最终final通知,不管是否异常,该通知都会执行,这种增强是 AOP联盟规范中不存在的 。在异常发生时,后置通知 无法执行,因为后置通知在方法返回之后,才能执行 ,发生异常,方法无法返回 。最终通知,相当于代码 finally 代码块,目标方法有没有错误,必须执行
6.DeclareParents 引介通知,相当于IntroductionInterceptor

所有AspectJ 增强,内部都可以传入 JoinPoint 连接点对象,通过该对象 可以获得拦截了哪个类哪个方法

代码示例:
OrderDao.java

package com.my.aspectj;

//订单接口
public interface OrderDao {
	
	public int save();
	public void update();
	public void delete();
	public void search();

}

OrderDaoImpl.java

package com.my.aspectj;

//被代理目标对象
public class OrderDaoImpl implements OrderDao {

	@Override
	public int save() {
		System.out.println("添加订单");
		return 10;
	}

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

	@Override
	public void delete() {
		System.out.println("删除订单");
		int d = 1/0;
	}

	@Override
	public void search() {
		System.out.println("查询订单");
	}

}

MyAspect.java

package com.my.aspectj;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;

//自定义 切面类 (在切面类当中 定义增强的方法)
public class MyAspect {

	// 前置增强 
	public void before(JoinPoint joinPoint){
		System.out.println("前置增强 ....." + joinPoint.toShortString());
	}
	
	// 后置增强
	public void afterReturning(JoinPoint joinPoint, Object returnValue){
		System.out.println("后置增强...."+ joinPoint.toShortString() + ", 方法返回值:" + returnValue);
	}
	
	// 环绕增强  (控制目标方法执行,该方法具有返回值)
	// ProceedingJoinPoint对象可以控制目标方法执行
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{ 
		System.out.println("环绕前增强....");
		Object result = proceedingJoinPoint.proceed();
		System.out.println("环绕后增强....");
		return null; 
	}
	
	// 抛出增强 (扑捉目标异常) Throwable对象是固定的
	public void afterThrowing(JoinPoint joinPoint, Throwable throwable){
		System.out.println(joinPoint.toShortString() + "目标方法出现异常.... 原因:" + throwable.getMessage());
	}
	
	// 最终通知
	public void after(JoinPoint joinPoint){
		System.out.println("最终增强..... 用于释放资源 ....");
	}
	
}


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"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
		
	<!-- AspectJ AOP 开发案例 -->
	<!-- 目标对象 -->
	<bean id="orderDao" class="com.my.aspectj.OrderDaoImpl" />
	<!-- 切面对象 -->
	<bean id="myAspect" class="com.my.aspectj.MyAspect"></bean>
	
	<!-- 进行AOP配置 -->
	<!-- 默认 有接口 使用 JDK代理,没有接口 使用 Cglib代理  -->
	<aop:config proxy-target-class="false">
		<!-- 整合AspectJ 框架的切面,含有多个切点和多个通知  -->
		<aop:aspect ref="myAspect"> <!-- 引用自定义切面类 -->
			<!-- 定义切点 -->
			<aop:pointcut expression="execution(* com.my.aspectj.OrderDaoImpl.s*(..))" id="myAspectPointcut1"/>
			<aop:pointcut expression="execution(* com.my.aspectj.OrderDaoImpl.delete(..))" id="myAspectPointcut2"/>
			<!-- 定义通知 -->
			<aop:before method="before" pointcut-ref="myAspectPointcut1"/>
			<aop:after-returning method="afterReturning" pointcut-ref="myAspectPointcut1" returning="returnValue"/>
			<aop:around method="around" pointcut-ref="myAspectPointcut1"/>
			<aop:after-throwing method="afterThrowing" pointcut-ref="myAspectPointcut2" throwing="throwable"/>
			<aop:after method="after" pointcut-ref="myAspectPointcut2"/>
		</aop:aspect>
	</aop:config>
	
</beans>

Test.java

package com.my.aspectj;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class Test {
	
	@Autowired
	@Qualifier("orderDao")
	private OrderDao orderDao;
	
	@org.junit.Test
	public void demo(){
		orderDao.search();
		orderDao.save();
		orderDao.update();
		orderDao.delete();
	}
	

}

运行结果:
这里写图片描述

使用注解开发AspectJ 实现 AOP编程
在applicationContext.xml 引入 aop名称名称,加入以下配置开启AspectJ自动代理

<aop:aspectj-autoproxy />

注解的作用:
@AspectJ 提供注解
@Aspect 定义切面
@Before 前置通知
@AfterReturning 后置通知
@Around 环绕通知
@AfterThrowing 异常通知
@After 最终通知
@Pointcut 定义切点

代码示例:
UserService.java

package com.my.annotation_aspectj;

public interface UserService {
	
	public void save();
	public int update();
	public void delete();
	public void select();

}

UserServiceImpl.java

package com.my.annotation_aspectj;

public class UserServiceImpl implements UserService {

	@Override
	public void save() {
		System.out.println("添加用户");
	}

	@Override
	public int update() {
		System.out.println("修改用户");
		return 0;
	}

	@Override
	public void delete() {
		System.out.println("删除用户");
		int[] arr = {};
		System.out.println(arr[0]);
	}

	@Override
	public void select() {
		System.out.println("查询用户");
	}

}

MyAspect.java

package com.my.annotation_aspectj;

import org.aspectj.lang.JoinPoint;
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.aspectj.lang.annotation.Pointcut;

//使用注解定义切面信息 
@Aspect 
public class MyAspect {

	// 前置增强 
	@Before(value="execution(* com.my.annotation_aspectj.UserServiceImpl.save(..))") // 这里value可以写切点表达式 或者 切点对象调用
	public void before(JoinPoint joinPoint){
		System.out.println("前置增强...." + joinPoint.toShortString());
	}
	
	// 后置增强
	// returning 用来指定返回值参数名称
	@AfterReturning(value="execution(* com.my.annotation_aspectj.UserServiceImpl.update(..))", returning="returnVal")
	public void afterReturning(JoinPoint joinPoint, Object returnVal){
		System.out.println("后置增强...." + joinPoint.toShortString() + ", 方法返回值:" + returnVal);
	}
	
	// 环绕增强
	@Around(value="execution(* com.my.annotation_aspectj.UserServiceImpl.s*(..))")
	public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
		System.out.println("环绕前增强...");
		Object result = proceedingJoinPoint.proceed(); // 执行目标方法
		System.out.println("环绕后增强...");
		return result;
	}
	
	// 抛出增强 
	@AfterThrowing(value="mypointcut()", throwing="throwable")
	// 使用 throwing 参数,指定异常对象传入参数名称
	public void afterThrowing(JoinPoint joinPoint , Throwable throwable){
		System.out.println(joinPoint.toShortString()+"目标方法发生异常,原因:"+ throwable.getMessage());
	}
	
	// 最终增强
	@After(value="mypointcut()||mypointcut2()")
	public void after(JoinPoint joinPoint){
		System.out.println("最终增强....");
	}
	
	// 单独定义一个切点
	@Pointcut(value="execution(* com.my.annotation_aspectj.UserServiceImpl.delete(..))")
	private void mypointcut(){} // 方法名就是切点名
	
	@Pointcut(value="execution(* com.my.annotation_aspectj.UserServiceImpl.save(..))")
	private void mypointcut2(){}
	
}

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"
       xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">
	
	<!-- 开启AspectJ自动代理-->	
	<aop:aspectj-autoproxy /> <!-- 自动读取切面类中注解信息,完成切面拦截代理  -->
	
	<!-- 目标 -->
	<bean id="userService" class="com.my.annotation_aspectj.UserServiceImpl"/>
	<!-- 切面 -->
	<bean id="myAspect" class="com.my.annotation_aspectj.MyAspect"></bean>
	
</beans>

Test.java

package com.my.annotation_aspectj;

import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:applicationContext.xml")
public class Test {
	
	@Autowired
	@Qualifier("userService")
	private UserService userService;
	
	@org.junit.Test
	public void demo(){
		userService.select();
		userService.save();
		userService.delete();
		userService.update();
		
	}
	

}

运行结果:
这里写图片描述

Coding Diary

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值