栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring-03

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring-03

1 aop编程的一些概念
2 使用 Spring 创建代理对象(注解方式)
3 关于切入点相关的参数的说明
4 环绕通知
 

一、AOP编程的一些概念

为什么要用AOP:可以看这篇文章(26条消息) 为什么需要使用Spring AOP(代理模式)_清思越的博客-CSDN博客

Aspect切面:横切性关注点的抽象

Joinpoint连接点:指的是拦截到的点,在spring中,指的就是被拦到的方法,比如addUser()等

pointCut 切入点:指的是对那些连接点进行拦截,比如,对所有的以get开头的方法进行计时

Advice 通知:拦到 Joinpoint 以后,要做的动作就叫通知,有前置通知、后置通知、最终通知、例外通知、环绕通知

Target 被代理的目标对象

Weave 织入:将Aspect 应用到目标对象的过程,经过织入以后,代理对象就产生了

二、使用 spring 创建代理对象(注解方式)

spring中进行AOP 编程,有两种方式:

        注解方式

        XML配置方式

1)注解方式:

  (1) 要导入相应的jar,加入配置构建路径
              aspectjweaver-1.8.9.jar 
              cglib-3.2.2.jar
         
                   如果用maven,则依赖如下
                         

  
         org.aspectj
         aspectjweaver
         1.8.9
  
  
       cglib
       cglib
       3.2.2
   

(2)创建spring的主配置文件,打开AOP的名称空间



	
	
	
	

(3)切面类

package com.aop;

import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

@Aspect //必须要加入切面注解
@Component  //交给spring管理
public class Myaspect {
	


	@Pointcut("execution(* com.dao.UserDaoImpl.*(..))") //切入点,想要对那些方法进行拦截
	private void anyMethod() {}
	
	//我要拦的不是pointCut里面的这些方法吗,那么在拦截这些方法之前我要执行我下面这个事
	@Before("anyMethod()")
	public void  beforeMethod() {
		System.out.println("前置通知触发了");
	}
	
	//后置通知:和前置通知相对应
	@AfterReturning("anyMethod()")
	public void afterMethod() {
		System.out.println("后置通知触发了");
	}
	//最终通知
	@After("anyMethod()")
	public void finallyMethod() {
		System.out.println("最终通知触发了");
	}
	
	//例外通知
	@AfterThrowing("anyMethod()")
	public void execptionMethod() {
		System.out.println("出现异常,例外通知触发了");
	}
	
	
	
}


                    execution() //表示拦截正在执行的方法
                    * //表示不管方法的返回值是什么都拦
                    com.dao.UserDaoImpl //表示拦截哪个包下的哪个类
                    * 表示不管这个方法的名字是什么
                    (..) //表示不管方法的参数是什么 

 3 关于切入点相关的参数的说明

  //例 通过 JoinPoint 叁数,得到方法的名称和得到目标对象
         

   @Before("anyMethodAAA()") 
            public void beforMethod(JoinPoint point) {
                //得到被拦截的方法的名称
                String methodName=point.getSignature().getName();
                if("delUser".equals(methodName)) {
                    System.out.println("将调用删除方法,日志已记录...");
                }
                
                //得到目标对象 
                UserDaoImpl imp=(UserDaoImpl)point.getTarget();
                System.out.println("目标对象的userName属性值是:"+imp.getUserName());
                
                //得到方法的参数
                Object  [] params =point.getArgs(); 
                for(Object param:params) {
                    System.out.println(param);
                }
                
                    
                System.out.println("前置通知触发了");
            }
        
         //例子 进一步限定切入点的条件 ,只拦截带两个参数的                  
            @Before("anyMethodAAA()&&args(a,b)")  //前置通知
            public void beforMethod(String a,String b) {
                System.out.println("得到的参数是"+ a  +" 和 "+ b);
                System.out.println("前置通知触发了");
            }
            
            这个通知,将只能作用于带两个 String 参数的方法
            
            


         //例子 取得方法执行的返回值
         

   @AfterReturning(pointcut = "anyMethodAAA()",returning = "result")  //后置通知
            public void afterMethod(int result) {
                System.out.println("方法的返回值是 "+result);
                System.out.println("后置通知触发了");
            }
            
            经过上面的处理以后,只有接口中有int型返回值的方法才能触发上面的后置通知,比如下面这个方法
                            public int getUserCount() {
                                         System.out.println("getUserCount 执行了");
                                         return 9/3;
                                    }
                        

            
         //例子 取得异常信息
             

@AfterThrowing(pointcut="anyMethodAAA()",throwing = "ex")
            public void exceptionMethod(Exception ex) {
                System.out.println("出错,异常信息是"+ex.getMessage());
                System.out.println("出现异常,例外通知触发了");
            }
  

4、环绕通知

		@Pointcut("execution(* com.dao.UserDaoImpl.*(..))")
		private void anyMethodAAA() {}
		
		@Around("anyMethodAAA()")
		public Object aroundMethod(ProceedingJoinPoint point) {
			Object result=null;
	
			String methodName=point.getSignature().getName();
			System.out.println("当前拦到的方法是:"+methodName);
			
			try {
				System.out.println("环绕通知 前置通知触发了");
				//让目标方法执行
				result=point.proceed();
				
				System.out.println("环绕通知 后置通知触发了");
				
			}catch(Throwable ex) {
				ex.printStackTrace();
				System.out.println("环绕通知 例通知触发了");
			}finally {
				System.out.println("环绕通知 最终知触发了");
			}
					
			return result;
			
		}

实际项目中,我们哪些地方需要做切面呢?

1)数据访问层

2)控制层

3)业务层

一般来说AOP主要用于日志记录、权限控制

             

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/293066.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号