aop两种代理
jdk代理和cglib代理
xml:
aop的五种通知类型
xml配置命令
步骤:
1、引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>5.3.16</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.9.4</version>
</dependency>
2、创建类型
如下
Target为目标类,Advice为通知类,Test测试
package com.aop5Advice;
public class TargetImpl implements Target {
@Override
public void show() {
System.out.println("目标方法");
int i=1/0;//测试异常通知
}
}
package com.aop5Advice;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
public class Advice {
//前置通知
public void before(JoinPoint jp){
System.out.println("前置通知:切入点"+jp.getSignature().getName());
}
//后置通知
public void afterReturning(JoinPoint jp){
System.out.println("返回通知:切入点"+jp.getSignature().getName());
}
//环绕通知
public Object around(ProceedingJoinPoint point)throws Throwable{//使用ProceedingJoinPoint接口实例作为参数获得目标对象的类名和方法名
System.out.println("这是环绕通知之前的部分!");
//调用目标方法
Object object = point.proceed();
System.out.println("这是环绕通知之前的部分!");
return object;
}
//异常通知
public void afterException(Throwable tr){
System.out.println("异常通知!"+tr.getMessage());
}
//最终通知
public void after(){
System.out.println("这是后置通知!");
}
}
3、添加aop的命名空间(applicationContext.xml)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
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/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
4、创建bean对象,目标对象和通知对象
<bean id="target" class="com.aop5Advice.TargetImpl"></bean>
<bean id="advice" class="com.aop5Advice.Advice"></bean>
5、aop配置
<aop:config>
<!-- 配置切点-->
<aop:pointcut id="pc" expression="execution(* com.aop5Advice.*.*(..))"/>
<!-- 配置切面-->
<aop:aspect ref="advice">
<!-- 前置通知-->
<aop:before method="before" pointcut-ref="pc"></aop:before>
<!-- 返回通知-->
<aop:after-returning method="afterReturning" pointcut-ref="pc"></aop:after-returning>
<!-- 环绕通知-->
<aop:around method="around" pointcut-ref="pc"></aop:around>
<!-- 异常通知-->
<aop:after-throwing method="afterException" pointcut-ref="pc" throwing="tr"></aop:after-throwing>
<!-- 后置通知-->
<aop:after method="after" pointcut-ref="pc"></aop:after>
</aop:aspect>
</aop:config>
aop切点表达式
6、测试
package com.aop5Advice;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Test {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationCOntext.xml");
Target target = (Target) applicationContext.getBean("target");
target.show();
}
}
注解:
package com.aop_zhujie;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
@Component
@Aspect
@Order(1)//通知的执行顺序,数字越小越早执行
public class Advice {
@Pointcut("execution(* com.aop_zhujie.*.*(..))")
public void p1(){}
@Before("p1()")
public void before(){
System.out.println("前置通知");
}
@After("p1()")
public void after(){
System.out.println("后置通知");
}
@Around("p1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕前通知");
Object proceed = pjp.proceed();
System.out.println("环绕后通知");
return proceed;
}
@AfterThrowing(value = "p1()" ,throwing = "tr")
public void afterThrowing(Throwable tr){
System.out.println("异常:"+tr);
}
@AfterReturning(value = "p1()",returning = "name")
public String afterReturning(String name){
System.out.println("最终通知"+name);
return name ;
}
}