一、什么是AOP AOP:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护,AOP在Spring中的作用:提供声明式事务,允许用户自定义切面二、Spring AOP的三种实现方式在pom.xml文件中导入所需的依赖\n\n\u003Cdependency>\n \u003CgroupId>org.aspectj\u003C/groupId>\n \u003CartifactId>aspectjweaver\u003C/artifactId>\n \u003Cversion>1.9.7\u003C/version>\n\u003C/dependency>\n1.通过Spring API实现AOP\n核心是通过编写增强类来继承Spring API提供的接口\n\n(1)编写业务接口和实现类\npublic interface UserService {\n public void add();\n public void delete();\n public void update();\n public void search();\n}\npublic class UserServiceImpl implements UserService{\n @Override\n public void add() {\n\n }\n\n @Override\n public void delete() {\n\n }\n\n @Override\n public void update() {\n\n }\n\n @Override\n public void search() {\n\n }\n}\n(2)编写增强类,并实现Spring API相关接口的方法\n补:Spring API相关接口\n\n通知类型 \t连接点\t实现接口\n前置通知\t方法前\tMethodBeforeAdvice\n后置通知\t方法后\tAfterReturningAdvice\n环绕通知\t方法前后\tMethodInterceptor\n异常抛出通知\t方法抛出异常\t\nThrowAdvice\n\n引介通知\t类中增加新的方法属性\tIntroductionInterceptor\npublic class BeforeLog implements MethodBeforeAdvice {\n @Override\n public void before(Method method, Object[] args, Object target) throws Throwable {\n System.out.println(target.getClass().getName()+\"的\"+method.getName()+\"方法被执行了\");\n }\n}\npublic class AfterLog implements AfterReturningAdvice {\n @Override\n public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {\n System.out.println(\"执行了\" + target.getClass().getName()\n +\"的\"+method.getName()+\"方法,\"\n +\"返回值:\"+returnValue);\n }\n}\n (3)在resource目录下新建applicationContext文件,实现java类的创建和aop的织入\n\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003Cbeans xmlns=\"http://www.springframework.org/schema/beans\"\n xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:aop=\"http://www.springframework.org/schema/aop\"\n xsi:schemaLocation=\"http://www.springframework.org/schema/beans\n https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd\"> \n \u003C!--注册bean--> \n \u003Cbean id=\"userService\" class=\"com.bai.spring.service.UserServiceImpl\"/>\n \u003Cbean id=\"beforeLog\" class=\"com.bai.spring.plus.BeforeLog\"/>\n \u003Cbean id=\"afterLog\" class=\"com.bai.spring.plus.AfterLog\"/> \n \u003C!--aop的配置-->\n \u003Caop:config>\n \u003C!--切入点 expression:表达式匹配要执行的方法-->\n \u003Caop:pointcut id=\"pointcut\" expression=\"execution(* com.bai.spring.service.UserServiceImpl.*(..))\"/>\n \u003C!--执行环绕; advice-ref执行方法 . pointcut-ref切入点-->\n \u003Caop:advisor advice-ref=\"log\" pointcut-ref=\"pointcut\"/>\n \u003Caop:advisor advice-ref=\"afterLog\" pointcut-ref=\"pointcut\"/>\n \u003C/aop:config>\n\n\u003C/beans>\n(4)编写测试类\npublic class TestAOP1 {\n public static void main(String[] args) {\n ApplicationContext context = new ClassPathXmlApplicationContext(\"applicationContext.xml\");\n //注意:动态代理代理的是接口,不是类\n UserService userService = (UserService) context.getBean(\"userService\");\n userService.search();\n }\n}\n测试结果\n\ncom.bai.spring.service.UserServiceImpl的search方法被执行了\n查询用户\n执行了com.bai.spring.service.UserServiceImpl的search方法,返回值:null \n\n(笔者在这里debug了半小时,后来发现是新版本的aspectjweaver1.9.7不支持,遂换成了aspectjweaver1.9.6,成功通过测试) \n\n2.通过自定义类来实现(推荐)
(1)自定义切入类\npublic class DIYPointCut {\n public void before(){\n System.out.println(\"---------方法执行前---------\");\n }\n public void after(){\n System.out.println(\"---------方法执行后---------\");\n }\n}\n
(2)去spring中配置\n\u003C!--注册bean-->\n\u003Cbean id=\"userService\" class=\"com.bai.spring.service.UserServiceImpl\"/>\n\u003Cbean id=\"diy\" class=\"com.bai.spring.diy.DIYPointCut\"/>\n\n\u003C!--aop的配置-->\n\u003Caop:config>\n \u003C!--切面 ref=增强类对象名-->\n \u003Caop:aspect ref=\"diy\">\n \u003C!--切入点可以有多个-->\n \u003Caop:pointcut id=\"diyPointCut\"\n expression=\"execution(* com.bai.spring.service.UserServiceImpl.*(..))\"/>\n \u003Caop:before method=\"before\" pointcut-ref=\"diyPointCut\"/>\n \u003Caop:after method=\"after\" pointcut-ref=\"diyPointCut\"/>\n \u003C/aop:aspect>\n\u003C/aop:config>
(3)编写测试类\npublic static void main(String[] args) {\n ApplicationContext context = new ClassPathXmlApplicationContext(\"applicationContext2.xml\");\n UserService userService = context.getBean(\"userService\", UserService.class);\n userService.add();\n}\n结果输出\n\n---------方法执行前---------\n增加用户\n---------方法执行后--------- \n\n3.使用注解实现
(1)自定义增强类(注解实现)\n@Aspect\npublic class AnnotationPointCut {\n\n @Before(\"execution(* pers.baishuai.spring.service.UserServiceImpl.*(..))\")\n public void before(){\n System.out.println(\"---------方法执行前---------\");\n }\n\n @After(\"execution(* pers.baishuai.spring.service.UserServiceImpl.*(..))\")\n public void after(){\n System.out.println(\"---------方法执行后---------\");\n }\n}\n
(2)在Spring配置文件中,注册bean,并增加支持注解的配置\n \u003Cbean id=\"userService\" class=\"pers.baishuai.spring.service.UserServiceImpl\"/>\n \u003Cbean id=\"annotationPointCut\" class=\"pers.baishuai.spring.diy.AnnotationPointCut\"/>\n \u003Caop:aspectj-autoproxy/>
(3)测试类与结果同(2)