Java通过Spring、Aspectj实现AOP(基于注解)

导包请参考这里

假设有如下目标接口和目标类:

public interface UserService {
	void addUser();
	String updateUser();
	void deleteUser();
}
import org.springframework.stereotype.Service;

@Service("userService")
public class UserServiceImpl implements UserService {

	@Override
	public void addUser() {
		System.out.println(" add user");
	}

	@Override
	public String updateUser() {	
		System.out.println(" update user");
		return "更新用户信息";
	}

	@Override
	public void deleteUser() {
		System.out.println(" delete user");
		int a = 1/0;
	}

}

新建切面类:

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


@Component()
@Aspect()
public class MyAspect {

	// 定义公共切入点表达式
	@Pointcut("execution(* com.kye.d_aspect.b_annotation.UserServiceImpl.*(..))")
	private void myPointCutExpress() {
	}

	@Before("execution(* com.kye.d_aspect.b_annotation.UserServiceImpl.*(..))")
	public void myBefor(JoinPoint joinPoint) {
		System.out.println("前置通知");
	}

	@AfterReturning(value = "myPointCutExpress()", returning = "object")
	public void myReturn(JoinPoint joinPoint, Object object) {
		System.out.println("后置通知,返回的值为:" + object);
	}

	@Around(value = "myPointCutExpress()")
	public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
		System.out.println("环绕前 通知:"+joinPoint.getSignature().getName());
		Object object = joinPoint.proceed();
		System.out.println("环绕后通知:"+joinPoint.getSignature().getName());
		return object;
	}

	@AfterThrowing(value = "myPointCutExpress()", throwing = "eThrowable")
	public void myThrowAble(JoinPoint joinPoint, Throwable eThrowable) {
		System.out.println("异常通知:" + eThrowable.getMessage());
	}
}

配置文件如下:

<?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"
	xmlns:context="http://www.springframework.org/schema/context"
	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">

	<!-- 有注解和xml id同名时,xml会覆盖注解 -->
	<!-- <bean id="userService" class="com.kye.d_aspect.b_annotation.UserServiceImpl2" ></bean> -->
	<context:component-scan base-package="com.kye.d_aspect.b_annotation"></context:component-scan>
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

</beans>

新建测试类:

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MyTest {

	@Test
	public void test1() {

		String path = "com/kye/d_aspect/b_annotation/beans.xml";

		ApplicationContext applicationContext = new ClassPathXmlApplicationContext(path);
		UserService userService = applicationContext.getBean("userService", UserService.class);
 
		userService.addUser();
		userService.updateUser();
		userService.deleteUser();
	}

}

输出结果:

befor...
c_spring_aop add user
after...
befor...
c_spring_aop update user
after...
befor...
c_spring_aop delete user
after...


另外我还尝试了一下,假设xml和注解中,存在同名的id,最后xml会覆盖注解。

原文地址:https://www.cnblogs.com/wugang/p/14232333.html