首页 > 编程语言 > 详细

Spring AOP切面编程

时间:2021-04-24 01:25:52      阅读:17      评论:0      收藏:0      [点我收藏+]

Spring07:AOP切面编程

基于代理类的在Spring AOP实现

Spring的AOP代理底层就是使用JDK动态代理模式实现的

Spring的通知类型
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(异常)

技术分享图片

Spring 对AspectJ开发的支持

导入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();
    	}
    
    }
    

    技术分享图片

  • 异常测试

技术分享图片

技术分享图片

Spring AOP切面编程

原文:https://www.cnblogs.com/liuzhihui021221/p/14695756.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!