Spring整合aspectj框架实现的aop

本文介绍如何在Spring框架中整合AspectJ实现更灵活的AOP编程。通过具体示例,展示了AspectJ的多种通知类型及其配置方法,并讨论了代理方式的选择。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring整合aspectj框架实现的aop

在现在的开发中使用这种方案比较多.

spring2.0以后它支持jdk1.5注解,而整合aspectj后可以使用aspectj语法,可以简化开发。

 

Aspect:切面 =切点+通知(多个切点与多个通知的组合)

AspectJ它是一个第三方框架,spring2.0后可以使用aspectJ框架的部分语法.

 

AspectJ框架它定义的通知类型有6

1.     前置通知Before相当于BeforeAdvice

2.     后置通知AfterReturning相当于AfterReturningAdvice

3.     环绕通知 Around 相当于MethodInterceptor

4.     抛出通知AfterThrowing相当于ThrowAdvice

5.     引介通知DeclareParents相当于IntroductionInterceptor

6.     最终通知After不管是否异常,该通知都会执行

相比spring的传统AOP Advice多了一个最终通知

第一步:创建目标(target)
public class UserServiceImpl implements UserService {

	@Override
	public int add() {
		int a = 10 / 0;
		System.out.println("add......");
		return 66;
	}

	@Override
	public void del() {
		System.out.println("del......");
	}

	@Override
	public void update() {
		System.out.println("update......");
	}

	@Override
	public void find() {
		System.out.println("find......");
	}

}

第二步:创建通知(增强  advice)

注意:aspectj中它的增强可以不实现任何接口,只需要定义出增强功能(方法)

//advice
public class UserServiceHelper{
	//前置通知+参数
	public void before(JoinPoint jp){
		System.out.println("拦截的目标类" + jp.getSignature().getDeclaringTypeName());
		System.out.println("拦截的方法" + jp.getSignature().getName());
		System.out.println("前置......");
	}
	//后置通知
	public void after(JoinPoint jp , Object val){
		System.out.println("返回值为" + val);
		System.out.println("后置.....");
	}
	//环绕通知
	public Object around(ProceedingJoinPoint pip) throws Throwable{
		System.out.println("环绕前");
		Object proceed = pip.proceed();
		System.out.println("环绕后");
		return proceed;
	}
	//异常抛出通知
	public void afterThrowing(JoinPoint jp,Throwable ex){
		System.out.println(ex);
		System.out.println("发现异常");
	}
	//最终通知
	public void end(JoinPoint jp){
		System.out.println(jp.getSignature().getName());
		System.out.println("结束");
	}

第三步:springxml配置文件中来配置

<aop:config>下的<aop:aspect>aspectJ框架用来声明切面的。

applicationContext.xml配置文件

<aop:config>
	<aop:aspect ref="userServiceAdvice">
		<aop:pointcut expression="execution(* com.itheima.aspectj.* .*(..))" id="myPointCut"/>
		<aop:before method="before" pointcut-ref="myPointCut" />       前置
		<aop:after-returning method="after" pointcut-ref="myPointCut" />	后置
		<aop:around method="around" pointcut-ref="myPointCut"/>		环绕
		<aop:after-throwing method="afterThrowing" pointcut-ref="myPointCut"/>	发现异常
		<aop:after method="end" pointcut-ref="myPointCut"/>			最终
	</aop:aspect>
</aop:config>
测试代码
//前置通知
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:applicationContext.xml")
public class AspectjTest {
	@Autowired
	private UserService userService;
	@Test
	public void test(){
		userService.del();
	}
加参数
public class UserServiceHelper {
	//前置通知+参数
	public void before(JoinPoint jp){
		System.out.println("拦截的目标类" + jp.getSignature().getDeclaringTypeName());
		System.out.println("拦截的方法" + jp.getSignature().getName());
		System.out.println("前置......");
	}
	//后置通知
	public void after(JoinPoint jp , Object val){
		System.out.println("返回值为" + val);
		System.out.println("后置.....");
	}
	//环绕通知
	public Object around(ProceedingJoinPoint pip) throws Throwable{
		System.out.println("环绕前");
		Object proceed = pip.proceed();
		System.out.println("环绕后");
		return proceed;
	}
	//异常抛出通知
	public void afterThrowing(JoinPoint jp,Throwable ex){
		System.out.println(ex);
		System.out.println("发现异常");
	}
	//最终通知
	public void end(JoinPoint jp){
		System.out.println(jp.getSignature().getName());
		System.out.println("结束");
	}

applicationContext.xml
<aop:config>
	<aop:aspect ref="userServiceAdvice">
		<aop:pointcut expression="execution(* com.itheima.aspectj.* .*(..))" id="myPointCut"/>
		<aop:before method="before" pointcut-ref="myPointCut" />		前置					
		<aop:after-returning method="after" pointcut-ref="myPointCut" returning="val" />  后置
		<aop:around method="around" pointcut-ref="myPointCut"/>		环绕
		<aop:after-throwing method="afterThrowing" pointcut-ref="myPointCut"  throwing="ex"/>  发现异常
		<aop:after method="end" pointcut-ref="myPointCut"/>	最终
	</aop:aspect>
</aop:config>


关于代理方式选择

springaop开发中,它使用的是代理方案,代理实现有两种:

1.     jdkproxy

2.     cglib

spring框架默认情况下,会对有接口的类使用proxy代理。没有接口的类使用cglib代理

如果为false  那么如果有实现接口 那么为jdkproxy 没有接口则为cglib

如果为true   那么不管有没有实现接口 默认为cglib

Proxy-target-class的值默认是false,它代表有接口使用proxy代理

问题:如果现在对目标要使用cglib代理(不考虑是否有接口)

只需要将proxy-target-class设置为true.





                
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值