irpas技术客

java Spring5之AOP_一条咸鱼

网络投稿 2594

面向切面编程,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。可以不修改源码添加新的功能。

目录

AOP术语

切入点表达式

注解实现AOP操作

xml配置文件实现AOP操作


AOP术语

连接点:可以被增强的方法。

切入点:实际被增强的方法。

通知:实际增强的逻辑部分称为通知。

通知类型:前置通知、后置通知、环绕通知、异常通知、最终通知。

切面:把通知应用到切入点的过程。

切入点表达式

设置对哪个类的哪个方法进行增强

语法结构: execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )

//对Test1类当中的所有方法进行增强 execution(* com.aoptest.Test1.*(..)) //对Test类当中的某一个方法进行增强 execution(* com.aoptest.Test1.方法名(..)) //对aoptest包中的所有类的所有方法进行增强 execution(* com.aoptest.*.*(..)) 注解实现AOP操作

首先创建被增强的类

package com.aoptest; import org.springframework.stereotype.Component; @Component public class Test1 { public void Show() { System.out.println("需要被增强的方法show"); } }

然后创建用于增强的类

package com.aoptest; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class Test2 { //通用的切入点表达式 @Pointcut(value = "execution(* com.aoptest.Test1.*(..))") public void pointcut() { } //前置通知 @Before注解表示前置通知 @Before(value = "execution(* com.aoptest.Test1.*(..))")//可以写入切入点表达式,也可以像下面一样设置通用的表达式填入方法即可 public void before() { System.out.println("前置通知"); } //最终通知 @After(value = "pointcut()")//效果和上面一样 public void after() { System.out.println("最终通知"); } //后置通知(返回通知)有异常的时候不执行 @AfterReturning(value = "pointcut()") public void afterReturning() { System.out.println("后置通知"); } //异常通知 @AfterThrowing(value = "pointcut()") public void afterThrowing() { System.out.println("异常通知"); } //环绕通知 @Around(value = "pointcut()") public void Around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable { System.out.println("环绕通知前"); proceedingJoinPoint.proceed(); System.out.println("环绕通知后"); } }

在xml文件当中开启注解扫描和Aspect生成代理对象

<!--开启注解扫描--> <context:component-scan base-package="com.aoptest"></context:component-scan> <!--开启Aspect生成代理对象--> <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

测试方法

@Test public void testAop() { ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml"); Test1 test1 = context.getBean("test1", Test1.class); test1.Show(); }

?输出结果

?当出现异常的时候,后置通知是不会执行的

如果有多个类都增强相同的方法,可以通过@Order注解来实现增强类的优先级设置。

//括号中的数字越小,优先级越高 @Order(1)

?例如我们再增加一个增强类Test3,设置优先级为0

package com.aoptest; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @Component @Aspect @Order(0) public class Test3 { @Before(value = "execution(* com.aoptest.Test1.*(..))") public void before() { System.out.println("前置通知Test3"); } }

输出结果

?可以发现,前置通知Test3是最先输出的。?

xml配置文件实现AOP操作

创建被增强的类

package com.aopxml; public class Book { public void buy() { System.out.println("buy"); } }

创建增强类

package com.aopxml; public class BookProxy { public void before() { System.out.println("前置通知"); } public void after() { System.out.println("最终通知"); } }

xml配置文件配置

<!--创建类--> <bean id="bookProxy" class="com.aopxml.BookProxy"></bean> <bean id="book" class="com.aopxml.Book"></bean> <!--配置aop增强--> <aop:config> <!--切入点--> <aop:pointcut id="pc" expression="execution(* com.aopxml.Book.*(..))"/> <!--配置切面--> <aop:aspect ref="bookProxy"> <!--设置增强作用在具体的方法上--> <aop:before method="before" pointcut-ref="pc"></aop:before><!--将前置通知作用在上面设置的pc切入点--> <aop:before method="after" pointcut-ref="pc"></aop:before> </aop:aspect> </aop:config>

测试方法

@Test public void testAop2() { ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml"); Book book = context.getBean("book", Book.class); book.buy(); }

输出结果


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #JAVA #Spring5之AOP #可以不修改源码添加新的功能 #切入点实际被增强的方法 #通知实际增强的逻辑部分称为通知