1.我对Aop的理解是在不改变源代码的基础上,扩展新的功能。
2.概念解释:
public class User {
/**
* 连接点:类里面可以被增强的方法
* 切入点:类里面已经被增强的方法
* 通知/增强:扩展的功能(逻辑)
* ①前置通知:在方法之前执行
* ②后置通知:在方法之后执行(出现异常也会执行)
* ③异常通知:方法出现异常时候执行
* ④返回通知:在后置之前执行(出现异常不会执行,方法成功返回后执行)
* ⑤环绕通知:在方法之前和之后执行(包住方法)
* 切面:把增强用到方法的过程叫增强(注意是一个过程)
*/
public void show(){//这个show方法叫 连接点
System.out.print("我是AopUser");
}
}
3.spring使用aspectj来做aop
①aspectj不是spring的一部分
②spring2.0新增了对aspectj的支持
4.实现aop有2种方式
①xml方式
②注解方式
5.导入jar包
在导入spring核心包的基础上,还需要导入aop相关的jar包
spring-aspects-5.0.5.RELEASE.jar
spring-aop-5.0.5.RELEASE.jar
aopalliance.jar
aspectjweaver-1.8.7.jar
6.常用表达式
execution(<访问修饰符>?<返回类型><方法名>(<参数>)<异常>)
(1) execution(* test3.AopUser.show1(..))
(2) execution( test3.AopUser.(..))
(3) execution( .*(..))
(4)execution( show(..))匹配所有show开头的方法
7.xml方式
①创建User类
@Component
public class User {
public void show(){
//int i=1/0;异常通知的时候用
System.out.println("我是User的show方法");
}
}
②创建增强类:
public class AopMethod {
public void before(){
System.out.println("我是前置通知");
}
public void after(){
System.out.println("我是后置通知");
}
public void last(){
System.out.println("我是最终通知");
}
public void exception(){
System.out.println("我是异常通知");
}
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("环绕通知开始");
proceedingJoinPoint.proceed();
System.out.println("环绕通知结束");
}
}
③applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="test3"></context:component-scan>
<bean id="AopMethod" class="test3.AopMethod"></bean>
<aop:config>
<aop:pointcut id="userShow" expression="execution(* test3.User.show(..))"></aop:pointcut>
<aop:aspect ref="AopMethod">
<!--<aop:before method="before" pointcut-ref="userShow"></aop:before>-->
<!--<aop:after method="after" pointcut-ref="userShow"></aop:after>-->
<!--<aop:around method="around" pointcut-ref="userShow"></aop:around>-->
<!-- <aop:after-throwing method="exception" pointcut-ref="userShow"></aop:after-throwing>-->
<!--<aop:after-returning method="last" pointcut-ref="userShow"></aop:after-returning>-->
</aop:aspect>
</aop:config>
④测试类MainTest
public class MainTest {
public static void main(String[] args){
//1.加载xml文件
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.拿到user对象,这里user是bean里面的id
User user = (User)context.getBean("user");
user.show();
}
}
⑤运行结果...
8.注解方式
@Before前置通知
@AfterReturning返回通知
@Around环绕通知
@AfterThrowing异常通知
@After(后置通知)最终通知(最终final通知,不管是否异常,该通知都会执行)
①在applicationContext.xml中加入
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
applicationContext.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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<context:component-scan base-package="test3"></context:component-scan>
<!--开启aop操作-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
②User类:
@Component
public class User {
public void show(){
//int i=1/0;//异常通知的时候用
System.out.println("我是User的show方法");
}
}
③AopMethod类:
@Component
@Aspect
public class AopMethod {
@Before(value = "execution(* test3.User.show(..))")
public void before(){
System.out.println("我是前置通知");
}
@AfterReturning(value = "execution(* test3.User.show(..))")
public void after(){
System.out.println("我是返回通知");
}
@After(value = "execution(* test3.User.show(..))")
public void last(){
System.out.println("我是后置通知");
}
@AfterThrowing(value = "execution(* test3.User.show(..))")
public void exception(){
System.out.println("我是异常通知");
}
@Around(value = "execution(* test3.User.show(..))")
public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
System.out.println("环绕通知开始");
proceedingJoinPoint.proceed();
System.out.println("环绕通知结束");
}
}
④MainTest类:
public class MainTest {
public static void main(String[] args){
//1.加载xml文件
ApplicationContext context=new ClassPathXmlApplicationContext("applicationContext.xml");
//2.拿到user对象,这里user是bean里面的id
User user = (User)context.getBean("user");
user.show();
}
}
⑤运行结果: