aop 好像都需要目标类有接口类具体什么原理我不太清楚,
程序结构如下
目标类实现类如下:
package com.qst.d_aspect_anno;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
@Service("userServerImplId")
public class UserServerImpl implements UserService {
@Override
public void addUser() {
System.out.println("com.qst.c_aspect_xml UserServer addUser");
}
@Override
public String updateUser() {
System.out.println("com.qst.c_aspect_xml UserServer updateUser");
return "返回值";
}
@Override
public void deleteUser() {
System.out.println("com.qst.c_aspect_xml UserServer deleteUser");
}
}
切面类如下:
package com.qst.d_aspect_anno;
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;
/*
* 切面类有多个通知
*/
@Component
@Aspect
public class MyAspect {
@Before("execution(* com.qst.d_aspect_anno.UserServerImpl.*(..))")
public void myBefore(JoinPoint joinPoint) {
System.out.println("前置通知"+joinPoint.getSignature().getName());
}
<!--声明公共切入点
<aop:pointcut expression="execution(* com.itheima.d_aspect.b_anno.UserServiceImpl.*(..))" id="myPointCut"/>
下面方法替代了上面的bean声明
myPointCut就相当于上面的id
-->
@Pointcut("execution(* com.qst.d_aspect_anno.UserServerImpl.*(..))")
private void myPointCut() {
}
@AfterReturning(value="myPointCut()",returning="ret")
public void myAfterReturning(JoinPoint joinPoint,Object ret) {
System.out.println("后置通知"+joinPoint.getSignature().getName()+"---->"+ret);
}
@Around(value="myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("前置环绕");
//手动执行目标方法
Object obj = joinPoint.proceed();
System.out.println("后置环绕");
return obj;
}
//必须有参数
@AfterThrowing(value="myPointCut()",throwing="e")
public void myAfterThrowing(JoinPoint joinPoint,Throwable e) {
System.out.println("抛出异常"+e.getLocalizedMessage());
}
@After("myPointCut()")
public void myAfter() {
System.out.println("最终通知");
}
}
配置文件
<?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">
<!-- 扫描类 -->
<context:component-scan base-package="com.qst.d_aspect_anno"></context:component-scan>
<!-- 扫描aop注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
测试类
package com.qst.d_aspect_anno;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
String xmlPath = "com/qst/d_aspect_anno/applicationcontext.xml";
ApplicationContext application = new ClassPathXmlApplicationContext(xmlPath);
UserService userService = (UserService) application.getBean("userServerImplId");
userService.addUser();
userService.deleteUser();
userService.updateUser();
}
}
每一个注解都替代了xml的一部分应用
着重学习execution(* com.qst.d_aspect_anno.UserServerImpl.*(…)) 切入点的定位
用法下面连接也有
xml实现连接如下(https://blog.csdn.net/qq_42603651/article/details/98231336)
可以对比查看