本人是一名物联网工程专业大二的学生,是互联网浪潮中一朵小小的浪花,写博客即是为了记录自己的学习历程,又希望能够帮助到很多和自己一样处于起步阶段的萌新。临渊羡鱼,不如退而结网。与其羡慕别人有顶尖的技术,还不如自己从慢慢摸索学习。终有一天,你也能称为别人“羡慕”的人 aop是一个规范,是动态化的一个规范,一个标准 怎么理解面向切面编程: 术语: 切面的三个关键要素: 声明对象你可以使用注解或者xml文件配置文件 xml文件: 切面类: 指定通知方法中的参数 具体使用: 定义格式 属性:value,切入点表达式 环绕通知: 属性: 特点: 特点:总是会执行,在目标方法后执行的 做资源清除的 定义和管理切入点,如果项目中有多个切入点是重复的,可以复用的,可以使用这个注解 属性value:切入点表达式 位置:自定义的方法上面 特点: 代码: 创建代理 本站所有文章均为原创,欢迎转载,请注明文章出处:爱敲代码的小游子
博客主页:https://blog.csdn.net/qq_44895397AOP:
面向切面编程,基于动态代理的,可以使用jdk,cglib两种代理方式 AOP就是动态代理的规范化,把动态代理的实现步骤,方法都定义好了,让开发人员用一种统一的方式, 使用动态代理。
1)需要在分析项目功能时找出切面 2)合理的安排切面的执行时间 3)合理的安排切面执行的位置
1)Aspect:切面,表示增强功能,完成某一个个的功能,非业务功能 常见的切面功能有日志、事务、统计信息、参数检查、权限验证 2)JoinPoint:连接点,连接业务方法和切面的位置,就某类中的业务方法 3)Pointcut:切入点,指多个连接点方法的集合,多个方法 4)目标对象:哪个类要增加功能,这个类就是目标对象 5)Advice:通知,通知表示切面功能执行的时间
1)切面的功能代码,切面干什么的 2)切面的执行位置,使用Pointcut表示切面的执行位置 3)切面的执行时间,使用Advice表示时间,在目标方法之前,还是目标方法之后
aop的技术实现框架:
1、spring:spring在内部实现了aop规范能够做aop的工作 spring主要在事务处理时使用aop 但是spring的aop比较笨重 2、aspectJ:一个开源的专门做aop的框架,spring框架集成了aspectJ框架,通过spring就能够使用aspectj的功能 实现方式有两种: 1、使用xml的配置文件:配置全局事务 2、使用注解,项目中使用aop一般都使用注解,aspectj有5个注解
切入点表达式:
execution表达式中明显就是方法的签名,黑色字体部分可省略,各部分用空格分开,可以用到一下符号:
实现步骤:
1、增加maven依赖
1)spring依赖 2)aspectj的依赖 3)单元测试依赖
<!--添加spring依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>5.2.5.RELEASE</version> </dependency> <!--aspectj依赖--> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>5.2.5.RELEASE</version> </dependency>
2、创建,目标类:接口和他的实现类
给类中的方法增加功能
3、创建切面类:普通的类
1)在类的上面加入@Aspectj 2)在类中定义方法,方法就是切面要执行的功能代码, 在方法上添加aspectj中的通知注解(@Before) 需要指定切入点表达式,execution()
4、创建配置文件:声明对象,把对象交给容器统一管理,
自动代理生成器,用来完成代理对象的自动创建功能的5、创建测试类,从spring容器中获取目标对象(实际是代理对象)
通过代理方法,实现aop的功能增强
代码:
<!--创建实现类对象--> <bean id="someServiceImpl" class="com.aspectj.domain.SomeServiceImpl"/> <!--创建切面类的对象--> <bean id="utilsTools" class="com.aspectj.domain.UtilsTools"/> <!-- 声明自动代理生成器,使用aspectj框架内部的功能,创建目标对象的代理对象 创建代理对象是在内存中实现的,修改目标对象的内存中的结构,创建为代理对象 所以目标对象就是被修改后的代理对象 --> <aop:aspectj-autoproxy />
/** * 切面类 * @Aspect :是aspectj框架中的注解 * 作用:表示当前的类是切面类 * 切面类:只用来给业务方法增加功能的类,在这个类中有切面的功能代码 * 位置:类定义的上面 */ @Aspect public class UtilsTools { /** * 定义方法,是实现切面功能的 * 方法定义的要求: * 1、公共方法:public * 2、方法没有返回值 * 3、方法名称自定义 * 4、方法可以有参数,也可以没有参数 * 如果有参数,参数不是自定义的,有几个参数类型可以使用 */ /** * @Before 前置通知注解 * 属性value,是切入点表达式,表示切面的功能执行的位置 * 位置:方法的上面 * public void doSome(String name,Integer age) */ @Before(value = "execution(public void com.aspectj.domain.SomeServiceImpl.doSome(String,Integer))") public void dolog() { //就是切面类要执行的功能代码 System.out.println("切面类" + new Date()); } }
JoinPoint:
业务方法,要加入切面功能的业务方法,
**作用是:**可以在通知方法中获取方法执行时的信息,例如方法名,方法参数
如果你的方法中需要用到方法的信息,就加入JoinPoint
这个JoinPoint参数的值是由框架赋予的,必须是第一个位置的参数;
使用方法:/** * JoinPoint :切入点 * 可以获取方法执行的信息 */ public void dolog(JoinPoint jp){ Object[] args = jp.getArgs(); for(Object arg:args){ System.out.println("参数"+arg); } System.out.println("切面"+new Date()); }
后置通知:@AfterReturning
属性:value:切入点表达式 return:自定义的变量,表示目标方法的返回值的 自定义的变量名必须和通知方法的形参名一样 位置:在方法定义的上面 特点: 1、在目标方法之后执行的 2、能够获取到方法的返回值,可以根据这个返回值的不同做不同的处理 3、可以修改这个返回值
@AfterReturning(value = "execution(* *..SomeServiceImpl.*(..))", returning = "o") public void doStudent(JoinPoint jp,Student o){ System.out.println("事务提交"); o.setName("多级包"); o.setAge(12); }
环绕通知:@Around
1、public 2、必须有一个返回值 3、方法名称自定义自定义 4、方法有参数,固定的参数,ProceedingJoinPoint
位置:在方法的定义上 特点: 1、他是功能最强的通知 2、在目标前后都能增强功能 3、控制目标方法是是否被调用执行 4、修改原来的目标方法的执行结果,影响最后的调用结果
等同于jdk动态代理的,InvocationHandler接口 参数:ProceedingJoinPoint pjp 等同于Method 作用:执行目标方法的 pjp.doSome(); 返回值:就是目标方法的执行结果,可以被修改 经常做的是事务
/** * 环绕通知:功能最强大,能在业务方法前后增强功能 * value:切片表达式 * ProceedingJoinPoint:参数用来执行方法 */ @Around(value = "execution(* *..SomeServiceImpl.*(..))") public Object MyAspectj(ProceedingJoinPoint pjp) throws Throwable { //控制方法是否执行 Object[] args = pjp.getArgs(); String name = ""; if (args != null && args.length > 1) { name = (String) args[0]; } Object proceed = null; System.out.println("方法后执行"); //目标方法的调用 if ("yky".equals(name)) { proceed = pjp.proceed();//相当于,method.invoke(),可以在这个方法前后增加功能 } System.out.println("方法前执行"); //修改方法的返回值 if(proceed != null){ proceed = "hello world"; } return proceed; }
异常通知:@AfterThrowing
1、public 2、没有返回值 3、方法名称自定义 4、方法可以有参数Exception,如果还有是JoinPoint
value:切入点表达式 throwing:表示目标方法抛出的异常对象,自定义变量 变量名必须和方法的参数名一样
最终通知:@After
1、public 2、没有返回值 3、方法名称自定义 4、没有参数,,如果有是JoinPoint
@Pointcut:
当使用@pointcut定义在一个方法的上面,此时方法的名称就是,切入点表达式的别名 其他通知中value属性可以使用这个方法名,代替切入点表达式了
@Before(value = "mycut()") public void before(){ System.out.println("前置通知"); } @After(value = "mycut()") public void finalDemo(){ System.out.println("最终通知"); } /** * @Pointcut: 用来管理切入点 */ @Pointcut(value = "execution(* *..SomeServiceImpl.*(..))")") public void mycut(){}
jdk动态代理实现:
1、创建目标类,SomeServiceImpl目标类,给他的doSome,doOther增加输出时间,事务 2、创建InvocationHandler接口的实现类,在这个实现类给目标方法增加功能 3、使用jdk中类Proxy,创建代理对象。实现创建对象的能力
public static void main(String[] args) { //创建目标对象 SomeService someService = new SomeServiceImpl(); //创建 MyInvocationHandler handler = new MyInvocationHandler(someService);
SomeService poxy = (SomeService) Proxy.newProxyInstance(someService.getClass().getClassLoader(), someService.getClass().getInterfaces(), handler); poxy.dosome(); } public class MyInvocationHandler implements InvocationHandler { private Object target; public MyInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //通过代理对象执行方法时调用执行invoke() Object res = null; utilsTools.dolog(); //执行目标类的方法,通过Method类实现 res = method.invoke(target, args);//实现类的方法 utilsTools.doTrans(); //执行结果 return res; } }
本网页所有视频内容由 imoviebox边看边下-网页视频下载, iurlBox网页地址收藏管理器 下载并得到。
ImovieBox网页视频下载器 下载地址: ImovieBox网页视频下载器-最新版本下载
本文章由: imapbox邮箱云存储,邮箱网盘,ImageBox 图片批量下载器,网页图片批量下载专家,网页图片批量下载器,获取到文章图片,imoviebox网页视频批量下载器,下载视频内容,为您提供.
阅读和此文章类似的: 全球云计算