Spring AOP之AspectJ的注解方式使用

需要导入的jar包,请看上一篇博客。

注解:

  • 如果使用注解进行aop开发,必须进行aspectj自动代理

<aop:aspectj-autoproxy>

  • 通知注解

@Before 前置

@AfterReturning 后置

@Around 环绕

@AfterThrowing 异常

@After 最终

  • 切面类

@Aspect

  •  声明切入点

@PointCut


(1)TeacherService.java服务接口

package com.itheima.e_aspectj_annotation;

public interface TeacherService {
	
	public void addTeacher();
	public String updateTeacher();

}


(2)TeacherServiceImpl.java实现接口

注意要把@Service注解加上。

package com.itheima.e_aspectj_annotation;

import org.springframework.stereotype.Service;

@Service
public class TeacherServiceImpl implements TeacherService {

	@Override
	public void addTeacher() {
		System.out.println("d_aspect anno  add teacher");
		//int i = 1/0;
	}

	@Override
	public String updateTeacher() {
		System.out.println("d_aspect anno  update teacher");
		return "来来来";
	}

}
(3)MyAspect.java类

注意注解,声明切面类。

package com.itheima.e_aspectj_annotation;

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;
import org.springframework.stereotype.Component;

/**
 * 切面类,含多个通知
 * @author <a>传智•左慈</a>
 *
 */
@Component
@Aspect  //<aop:aspect ref="myAspect">
public class MyAspect {
	
	
	//@Before("execution(* com.itheima.e_aspectj_annotation.*.*(..))")
	public void myBefore(JoinPoint joinPoint){
		System.out.println("前置通知, 方法名称:" + joinPoint.getSignature().getName());
	}
	
	//@AfterReturning(value="execution(* com.itheima.e_aspectj_annotation.*.*(..))",returning="xxx")
	public void myAfterReturning(JoinPoint joinPoint,Object xxx){
		System.out.println("后置通知, 返回值:" + xxx);
	}
	
	//@Around("execution(* com.itheima.e_aspectj_annotation.*.*(..))")
	public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
		
		System.out.println("前");
		//必须执行目标方法
		Object obj = joinPoint.proceed();
		
		System.out.println("后");
		return obj;
	}
	
	//@AfterThrowing(value="execution(* com.itheima.e_aspectj_annotation.*.*(..))" ,throwing="e")
	public void myAfterThrowing(JoinPoint joinPoint, Throwable e){
		System.out.println("抛出异常通知, " + e.getMessage());
	}
	@After("myPonitCut()")
	public void myAfter(){
		System.out.println("最终");
	}
	
	/**
	 * 使用 @Pointcut 声明切入点表达式,必须修饰在方法:私有,没有返回值,方法名任意
	 * 在通知中可以通过方法获得,相当于调用方法。
	 */
	@Pointcut("execution(* com.itheima.e_aspectj_annotation.*.*(..))")
	private void myPonitCut(){
		
	}

}


(4)beans.xml配置文件

实际上只有两个注解有用。

1、声明扫描的包

<context:component-scan base-package="com.itheima.e_aspectj_annotation"></context:component-scan>  

2、

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>


<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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
       					   http://www.springframework.org/schema/context
       					   http://www.springframework.org/schema/context/spring-context.xsd
       					   ">
	<!-- 1 目标类 
	@Service
	public class TeacherServiceImpl implements TeacherService {
	<bean id="teacherServiceId" class="com.itheima.d_aspectj_xml.TeacherServiceImpl"></bean>
	-->
	<!-- 2 切面类(多个通知)
	@Component
	public class MyAspect {
	<bean id="myAspect" class="com.itheima.d_aspectj_xml.MyAspect"></bean>
	 -->
	 <!-- 扫描 -->
	 <context:component-scan base-package="com.itheima.e_aspectj_annotation"></context:component-scan>
	 
	<!-- 3 aop编程 
		3.1特殊切面,配置一个通知 和 一个切入点
			<aop:advisor advice-ref="一个通知" pointcut-ref="一个切入点"/>
		3.2 就是切面,声明配置多个通知和多个切入点
			<aop:aspect ref="">确定切面类,从而获得多个通知
	-->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
	
	<!--  
	<aop:config>
	
		@Aspect  //<aop:aspect ref="myAspect">
		public class MyAspect {
		<aop:aspect ref="myAspect">
		
			3.2 配置切入点
			<aop:pointcut expression="execution(* com.itheima.d_aspectj_xml.*.*(..))" id="myPonitCut"/>
			3.3 声明通知类型 
				#1 前置通知 , 目标方法之前执行。
					* 第一个参数为JoinPoint,可以获得目标方法名等。
				<aop:before method="myBefore" pointcut-ref="myPonitCut"/>
				#2 后置通知,目标方法之后执行,可以获得返回值。 通过“returning”属性配置第二个参数的名称,获得返回值的,类型必须Object
					* 第一个参数为:JoinPoint
					* 第二个参数为:Object xxx
				<aop:after-returning method="myAfterReturning" pointcut-ref="myPonitCut" returning="xxx"/>
				#3 环绕通知, 目标方法前后
					方法要求:public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable{
					执行目标方法:joinPoint.proceed();
				<aop:around method="myAround" pointcut-ref="myPonitCut"/>
				#4 抛出异常通知,目标方法出现异常时才执行。通过“throwing”属性配置第二个参数的名称,获得具体的异常信息,类型必须是Throwable
					* 第一个参数为:JoinPoint
					* 第二个参数为:Throwable e
				<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPonitCut" throwing="e"/>
			<aop:after method="myAfter" pointcut-ref="myPonitCut"/>			
		</aop:aspect>
		
	</aop:config>
	-->
	
	
	
	
</beans>

(5)TestApp.java单元测试类

package com.itheima.e_aspectj_annotation;

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

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:com/itheima/e_aspectj_annotation/beans.xml")
public class TestApp {
	
	@Autowired
	private TeacherService teacherService;
	
	@Test
	public void demo01(){
		//获得目标类
//		String xmlPath = "com/itheima/e_aspectj_annotation/beans.xml";
//		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
//		TeacherService teacherService = (TeacherService) applicationContext.getBean("teacherServiceId");
		teacherService.addTeacher();
		teacherService.updateTeacher();
	}

}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dmfrm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值