谈到Spring,相信只要从事Java开发的同学都知道Spring的两大核心:AOP 和IOC, 本文只谈AOP。
AOP的概念,相信很多人面试都被问到过,但每次都弄的不太清楚,比如: 什么是切面,什么是增强,什么是切点...
面对如此晦涩难懂的名词,本文尝试通过代码帮助大家理解并记忆这些概念,为了便于理解,这里使用xml配置方式,实际工作中用的比较多的还是注解方式。话不多说,撸代码:
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<bean id="userService" class="top.lovelily.spring.service.impl.UserServiceImpl"/>
<bean id = "helloArroundAdvice" class="top.lovelily.spring.aop.HelloAroundAdvice"/>
<bean id ="logAspect" class="top.lovelily.spring.aop.LogAspect"/>
<aop:config>
<!--第一种:aspect方式配置切面-->
<aop:aspect id="logAspect" ref="logAspect">
<!--execution(返回值 包名.接口名.方法名(参数)-->
<!--execution(User top.lovelily.spring.service.UserService.get())-->
<aop:pointcut id="serviceOperation"
expression="execution(* top.lovelily.spring.service.*.*(..))"/>
<aop:around
pointcut-ref="serviceOperation"
method="doAroundLog"/>
</aop:aspect>
<!--第一种:aspect方式配置切面-->
<!--第二种:advisor方式配置切面-->
<aop:pointcut id="myPointcut" expression="execution(* top.lovelily.spring.service.*.*(..))"/>
<aop:advisor advice-ref="helloArroundAdvice" pointcut-ref="myPointcut"/>
<!--第二种:advisor方式配置切面-->
</aop:config>
</beans>
beans.xml
public class LogAspect {
public Object doAroundLog(ProceedingJoinPoint joinPoint) {
System.out.println("begin...");
try {
Object result = joinPoint.proceed();
// execution(void top.lovelily.spring.service.UserService.save(User))
System.out.println(joinPoint);
// top.lovelily.spring.service.impl.UserServiceImpl@3e3047e6
System.out.println(joinPoint.getTarget());
return result;
} catch (Throwable throwable) {
throwable.printStackTrace();
}
System.out.println("end...");
return null;
}
}
LogAspect.java
public class TestAop {
public static void main(String[] args) {
UserService userService1 = new UserServiceImpl();
System.out.println(userService1 instanceof UserServiceImpl); // true
System.out.println(userService1 instanceof UserService); //true
System.out.println("------------------------------------");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:beans.xml");
Object bean = context.getBean("userService");
System.out.println(bean instanceof Advised); // true
System.out.println(bean instanceof UserService); // true
UserService userService = (UserService) bean;
User user = new User();
// userService.save(user);
User user1 = userService.get();
System.out.println(user1);
}
}
TestAop .java
通过代码运行结果,总结AOP相关概念:
-
joinpoint:连接点,程序执行时的某个特定的点,在Spring中就是某一个方法的执行,如程序中打印的execution(User top.lovelily.spring.service.UserService.get())
-
pointcut:切点,方法的集合,包含多个joinpoint,通常会有通配符,xml配置文件中的execution(* top.lovelily.spring.service.*.*(..))
-
aspect:切面,可以横跨多个class,封装了一些操作(advice), 就是个类,封装了具体要插入的操作,比如LogAspect.java记录了开始结束日志。
-
advice:通知,在切点执行的操作,before, after,aroud:具体要添加的操作(方法), 就是个方法,比如LogAspect.java中的doAroundLog方法
-
advisor:通知器,从advisor方式配置切面方式的配置中可以看出,就是pointcut和advice的适配
-
advised: 也称为目标对象,或者说被代理对象,即我们的bean
如果觉得还不错的话,关注、分享、在看, 原创不易,且看且珍惜~