1、自定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(value=ElementType.METHOD)
public @interface AdviceAnnotation {
String name();
}
2、service层
public interface AdviceService {
void study(String name) throws Exception;
}
3、实现类
@Service
public class AdviceServiceImpl implements AdviceService {
@AdviceAnnotation(name = "我是注解name!!!")
public void study(String name) throws Exception {
System.out.println("好好学习,天天向上");
throw new Exception("my god!!");
}
}
4、切面
@Aspect // 切面注解
@Component
public class StudyAdvice {
@Before(value = "execution(* com.teng.advice.service.impl.AdviceServiceImpl.study(..))"
+ "&& args(name)",argNames="name")
private void studyBefore(String name){
System.out.println(String.format("获取到的参数:%s", name)); // 获取切入方法上的参数
System.out.println("学习之前先打局游戏!");
}
@After(value="@annotation(com.teng.advice.annotation.AdviceAnnotation) &&"
+ "execution(* com.teng.advice..*.*(..))")
private void studyAfter(AdviceAnnotation ad){
System.out.println("学累了再打局游戏!");
}
@Around("execution(* com.teng.advice..*.*(..)) && @annotation(ad)")
private Object studyAround(ProceedingJoinPoint pjp,AdviceAnnotation ad) throws Throwable{ // 环绕通知需要有返回值
System.out.println("前置通知:还是打游戏");
System.out.println(String.format("注解name:%s", ad.name())); // 获取切入方法上的注解
Object result = pjp.proceed();
System.out.println("后置通知:依旧打游戏");
return result;
}
@AfterThrowing(pointcut="execution(* com.teng.advice..*.*(..))",throwing="ex")
private void studyThrow(Throwable ex){
System.out.println(ex.getMessage());
}
// @AfterReturning(returning="rvt" ,pointcut="execution(* com.teng.advice..*.*(..))")
// public void test(Object rvt){
// System.out.println("获取目标方法返回值:" + rvt);
// }
}
5、运行
@SpringBootApplication
public class BootTestApplication
{
public static void main( String[] args )
{
SpringApplication.run(BootTestApplication.class, args);
}
@Autowired
private AdviceService adviceService;
@PostConstruct
public void init() throws Exception{
adviceService.study("小耿");
}
}
6、打印结果
前置通知:还是打游戏
注解name:我是注解name!!!
获取到的参数:小耿
学习之前先打局游戏!
好好学习,天天向上
学累了再打局游戏!
my god!!