Spring的AOP代理底层就是使用JDK动态代理模式实现的
org.aopalliance.intercept.MethodInterceptor
环绕通知,如:用于日志和事务
org.springframework.aop.MethodBeforeAdvice
前置通知,如:权限管理
org.springframework.aop.AfterReturningAdvice
后置通知,如:关闭流,上传文件、删除临时文件
org.springframework.aop.ThrowsAdvice
异常通知,如:处理异常记录日志
org.springframework.aop.IntroductionInterceptor
介入增强,如:直接增加一个方法
导包:
创建切面类:
实现MethodInterceptor
接口
package com.znsd.aop.notice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
public class Method implements MethodInterceptor{
@Override
public Object invoke(MethodInvocation method) throws Throwable {
// TODO Auto-generated method stub
check_Permisssions();
Object object = method.proceed();
log();
return object;
}
public void check_Permisssions() {
System.out.println("检查权限");
}
public void log() {
System.out.println("日志记录");
}
}
实现AfterReturningAdvice
接口
package com.znsd.aop.notice;
import java.lang.reflect.Method;
import org.springframework.aop.AfterReturningAdvice;
public class After implements AfterReturningAdvice{
@Override
public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
// TODO Auto-generated method stub
System.out.println("前置通知");
}
}
实现MethodBeforeAdvice
接口
package com.znsd.aop.notice;
import java.lang.reflect.Method;
import org.springframework.aop.MethodBeforeAdvice;
public class Before implements MethodBeforeAdvice{
@Override
public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
// TODO Auto-generated method stub
System.out.println("后置通知");
}
}
实现ThrowsAdvice
接口
package com.znsd.aop.notice;
import org.springframework.aop.ThrowsAdvice;
public class Throw implements ThrowsAdvice{
public void afterThrowing(Exception e) throws Throwable{
System.out.println("出异常了..."+e);
}
}
实现IntroductionInterceptor
接口 注:待完善,暂时没有例子
package com.znsd.aop.notice;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.IntroductionInterceptor;
public class Introduction implements IntroductionInterceptor{
@Override
public boolean implementsInterface(Class<?> arg0) {
// TODO Auto-generated method stub
return false;
}
@Override
public Object invoke(MethodInvocation arg0) throws Throwable {
// TODO Auto-generated method stub
return null;
}
}
定义接口
package com.znsd.aop.service;
import java.util.List;
public interface UserService {
List ListUser();
Object getUser();
boolean deleteUser();
boolean updateUser();
boolean insertUser() throws Exception;
}
定义实现类
package com.znsd.aop.service;
import java.util.List;
public class UserServiceImpl implements UserService{
@Override
public List ListUser() {
// TODO Auto-generated method stub
System.out.println("获取List");
return null;
}
@Override
public Object getUser() {
// TODO Auto-generated method stub
System.out.println("获取one");
return null;
}
@Override
public boolean deleteUser() {
// TODO Auto-generated method stub
System.out.println("删除");
return false;
}
@Override
public boolean updateUser() {
// TODO Auto-generated method stub
System.out.println("修改");
return false;
}
@Override
public boolean insertUser() throws Exception{
// TODO Auto-generated method stub
System.out.println("增加");
throw Ecxeption();
return false;
}
}
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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 1 目标类 -->
<bean id="userService" class="com.znsd.aop.service.UserServiceImpl"></bean>
<!-- 2 切面类 -->
<bean id="method" class="com.znsd.aop.notice.Method"></bean> <!-- 植入环绕通知 -->
<bean id="before" class="com.znsd.aop.notice.Before"></bean> <!-- 植入前置通知 -->
<bean id="after" class="com.znsd.aop.notice.After"></bean> <!-- 植入后置通知 -->
<bean id="throw" class="com.znsd.aop.notice.Throw"></bean> <!-- 异常后通知 -->
<bean id="introduction" class="com.znsd.aop.notice.Introduction"></bean> <!-- 介入通知:没有使用 -->
<!-- 3 使用Spring代理工厂注册一个ID为userDaoProxy的对象 -->
<bean id="userServiceProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<!-- 3.1代理的目标对象 -->
<property name="target" ref="userService"></property>
<!-- 3.2代理实现的接口 -->
<property name="proxyInterfaces" value="com.znsd.aop.service.UserService"/>
<!-- 3.3指定切面 -->
<property name="interceptorNames">
<value>method,after,before,throw</value>
</property>
<!-- 3.4指定代理方式,true:使用cglib,false(默认):jdk -->
<property name="proxyTargetClass" value="false"/>
</bean>
</beans>
测试结果1(环绕,前置,后置)
测试结果2(异常)
导入jar包:
基于XML的声明是AspectJ:
编写切面类
package com.znsd.aop.notice;
import org.aspectj.lang.ProceedingJoinPoint;
public class MyAspectJ {
public void myBofore() {
System.out.println("我的前置通知");
}
public void myAfter() {
System.out.println("我的后置通知");
}
public void myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
System.out.println("开启事务");
proceedingJoinPoint.proceed();
System.out.println("关闭事务");
}
//异常通知
public void myAfterThrowing(Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
//最终通知
public void myLast(){
System.out.println("最终通知:模拟方法结束后的释放资源。。。。");
}
}
配置切面、切入点 、通知
<?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"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--1.目标类 -->
<bean id="userService" class="com.znsd.aop.service.UserServiceImpl"></bean>
<!--2.切面 -->
<bean id="myAspectJ" class="com.znsd.aop.notice.MyAspectJ"></bean>
<!-- 3.AOP编程 -->
<aop:config>
<!-- 3.0配置切面 -->
<aop:aspect id="myAspect" ref="myAspectJ">
<!--3.1配置切入点,通知最后增强哪些方法-->
<aop:pointcut expression="execution(* com.znsd.aop.service.*.*(..))" id="myPointcut" />
<aop:before method="myBofore" pointcut-ref="myPointcut"/>
<aop:after method="myAfter" pointcut-ref="myPointcut"/>
<aop:around method="myAround" pointcut-ref="myPointcut"/>
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPointcut" throwing="e"/>
<aop:around method="myLast" pointcut-ref="myPointcut"/>
</aop:aspect>
</aop:config>
</beans>
测试
package com.znsd.aop.test;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.znsd.aop.service.UserService;
class AspectJTest {
@Test
void test() {
ApplicationContext ap = new ClassPathXmlApplicationContext("base.xml");
UserService userService = ap.getBean("userService",UserService.class);
userService.getUser();
}
}
异常测试
原文:https://www.cnblogs.com/liuzhihui021221/p/14695756.html