天天看点

spring AOP——通过注解的方式实现目录

spring AOP——用注解的方式实现

  • 目录
    • 说明
    • 配置applicationContext.xml
    • 切面类MyAspect.java
    • 自定义注解@Method
    • 总结

目录

说明

本例子不是web项目。

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

	<!-- 开启自动扫描text3_AOP_text4包下的所以类的注释 -->
	<context:component-scan base-package="text3_AOP_text4" />
	<!-- 开启aspectj注释 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
           

说明:

用注解的方式,可以大大的减少配置操作

切面类MyAspect.java

切面类:MyAspect.java,

代码片

.

package text3_AOP_text4;
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;

//注册一个bean,是一个切面
@Component
@Aspect
public class MyAspect {
	// 连接点,方法
	@Pointcut("execution(* text3_AOP_text3.StudentImpl.*(..))")
	public void pointcut1() {
	}

	// 连接点,类
	@Pointcut(argNames = "pointcut2", value = "within(text3_AOP_text3.StudentImpl.*)")
	public void pointcut2() {
	}

	// 前置通知方法
	@Before("pointcut()")
	public void before(JoinPoint joinPoint) {
		System.out.println("前置通知---方法名: " + joinPoint.getSignature().getName());
	}

	// 带参数的前置通知方法,且参数名是(arg1,arg2,arg3,...)
	@Before("pointcut() && args(arg1,arg2,arg3)")
	public void beforeWithParam(JoinPoint joinPoint,String arg1, String arg2, String arg3) {
		System.out.println(arg1);
	}

	// 带参数的前置通知方法,且可以获得附加参数,@Method类型是一个注解,自定义参数名Method
	@Before("pointcut() && @annotation(Method)")
	public void beforeWithAnnotaion(Method Method) {
		System.out.println("BeforeWithAnnotation." + Method.value());
	}

	// 返回后通知方法,返回值名re,
	@AfterReturning(pointcut = "pointcut2", returning = "re")
	public void afterReturning(JoinPoint joinPoint, Object re) {
		System.out.println("后置通知---方法名: " + joinPoint.getSignature().getName() + ", 返回参数re: " + re);
	}

	// 异常通知方法,异常变量为e
	@AfterThrowing(pointcut = "pointcut()", throwing = "e")
	public void afterThrowing(JoinPoint joinPoint, Throwable e) {
		System.out.println("异常通知: " + "出现异常的方法名: " + joinPoint.getSignature().getName() + ", 异常信息e: " + e.getMessage());
		System.exit(0);
	}

	// 后通知方法
	@After("pointcut()")
	public void after(JoinPoint joinPoint) {
		System.out.println("后通知---方法名: " + joinPoint.getSignature().getName());
	}

	// 环绕通知方法
	@Around("pointcut()")
	public Object around(ProceedingJoinPoint joinPoint) {
		Object re = null;
		try {
			System.out.println("环绕通知前");
			re = joinPoint.proceed();
			System.out.println("环绕通知后");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return re;
	}

	// 有参数的环绕通知方法,执行的上下文ProceedingJoinPoint
	@Around("pointcut() && args(name)")
	public Object aroundInit(ProceedingJoinPoint joinPoint, String name) {
		System.out.println("姓名:" + name);
		Object re = null;
		try {
			System.out.println("环绕通知前");
			re = joinPoint.proceed();
			System.out.println("环绕通知后");
		} catch (Throwable e) {
			e.printStackTrace();
		}
		return re;
	}
	
	//在使用People对象时,可以自主的将People对象强制转为FBIImpl对象
	@DeclareParents(value = "text3_AOP_text3.People", defaultImpl = text3_AOP_text4.FBIImpl.class)
    public FBI fbi;
}

           

说明:

--------------------------------------------------------------------------------------------------------------------------------------------
	 * 了解一下spring aop的两个接口的主要方法:  
	 * 1)JoinPoint 
	 * 		java.lang.Object[] getArgs():获取连接点方法的参数集合 
	 * 		Signature getSignature() :获取连接点的方法对象;
	 * 		java.lang.Object getTarget() :获取连接点所在类的目标对象; 
	 * 		java.lang.Object getThis():获取切面对象本身;  
	 * 2)ProceedingJoinPoint 
	 * 	ProceedingJoinPoint继承JoinPoint子接口,新增了两个用于执行连接点方法的方法:
	 * 		java.lang.Object proceed() throws java.lang.Throwable:通过反射执行目标对象的连接点处的方法;
	 * 		java.lang.Object proceed(java.lang.Object[] args) throws java.lang.Throwable:通过反射执行目标对象连接点处的方法,不过使用新的入参替换原来的入参。 
	 * 
           

spring不能自动识别Aspect注解,需要带上@Component注解来标注

自定义注解@Method

@Method注解,

代码片

.

package text3_AOP_text4;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
//方法上,运行时
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Method {	
	String value();
}
           

说明:

注解用在方法上,运行时有效

总结

1. 使用注解的方式来实现AOP相对于API方式和配置方式更加方便,可以大大的简化开发过程。
**引用包是最大的困难(一步一步来)**
           

继续阅读