你们好,我是IT修真院深圳分院第12期的JAVA学员,一枚正直纯洁善良的java程序员。html
今天给你们分享一下,修真院官网Java任务3,深度思考中的知识点—Spring Aop?java
1.背景介绍
一、什么是AOP程序员
1)在OOP(面向对象编程)中,正是这种分散在各处且与对象核心功能无关的代码(横切代码)的存在,使得模块复用难度增长。
2)AOP则将封装好的对象剖开,找出其中对多个对象产生影响的公共行为,并将其封装为一个可重用的模块,这个模块被命名为“切面”(Aspect)
3)切面将那些与业务无关,却被业务模块共同调用的逻辑提取并封装起来,减小了系统中的重复代码,下降了模块间的耦合度,同时提升了系统的可维护性、提升了开发的效率和程序的可复用性。spring
二、AOP与OOP的区别编程
1)AOP能够说是OOP(面向对象编程)的补充和完善。OOP引入封装、继承、多态等概念来创建一种对象层次结构,用于模拟公共行为的一个集合。
2)不过OOP容许开发者定义纵向的关系,但并不适合定义横向的关系
3)例如日志功能。日志代码每每横向地散布在全部对象层次中,而与它对应的对象的核心功能毫无关系。对于其余类型的代码,如安全性、异常处理和透明的持续性也都是如此,这种散布在各处的无关的代码被称为横切(cross cutting)。
4)在OOP设计中,它致使了大量代码的重复,而不利于各个模块的重用。 安全
三、AOP的思想app
1) AOP的核心思想是帮助咱们在扩展功能(方法)时能够不依靠修改源代码来实现。
2)其采起横向抽取机制,规避了传统面向对象中纵向继承体系的重复性高耦合代码。框架
2.知识剖析编码
一、为何要使用aopspa
1)为了方便,用了aop能让你少写不少代码 2)为了更清晰的逻辑,可让你的业务逻辑去关注本身自己的业务,而不去想一些其余的事情,这些其余的事情包括:安全,事物,日志等。 3)为了下降以前传统面向对象中采用纵向继承体系加强方法致使的耦合度太高的问题: 4)提升了代码的复用性
二、浅析AOP思想的发展及原理
发展:修改源代码————采用OOP纵向继承体系————采用AOP横向织入
实现原理:经过动态代理建立代理对象来实现,默认使用Java动态代理来建立AOP代理,当须要代理的类不是代理接口的时候,Spring会切换为使用CGLIB代理
三、aop专业术语
1.通知(Advice):通知定义了切面是什么以及什么时候使用;里面就是加强方法的逻辑,分为前置加强,后置加强,环绕加强,最终加强,异常加强。
2.链接点(JoinPoint):链接点是在应用执行过程当中可以插入切面的一个点。这个点能够是调用方法时,抛出异常时,甚至修改一个字段时。切面代码能够利用这些点插入到应用的正常流程中,并添加新的行为。
3.切入点(Pointcut)*:切点有助于缩小切面所通知的链接点的范围。(何处)
4.切面(Aspect)*:切面是通知和切点的结合。通知和切点定义了切面的所有内容——它是什么,在什么时候何处完成其功能。
5.目标(target):被加强的方法所在的那个类,也就是真正的业务逻辑,他能够在绝不知情的状况下,被织入切面。而本身专一于业务自己的逻辑。
6.代理(proxy):目标类被加强后产生的代理类
7.织入(weaving):把加强应用到目标类的过程
8:引入(Introduction) 引入容许咱们向现有的类添加新方法或属性,从而无需修改这些现有类的状况下,让他们具备新的行为和状态
四、通知类型介绍
(1)Before:在目标方法被调用以前作加强处理,@Before只须要指定切入点表达式便可
(2)AfterReturning:在目标方法正常完成后作加强,@AfterReturning除了指定切入点表达式后,还能够指定一个返回值形参名returning,表明目标方法的返回值
(3)AfterThrowing:主要用来处理程序中未处理的异常,@AfterThrowing除了指定切入点表达式后,还能够指定一个throwing的返回值形参名,能够经过该形参名 来访问目标方法中所抛出的异常对象
(4)After:在目标方法完成以后作加强,不管目标方法时候成功完成。@After能够指定一个切入点表达式
(5)Around:环绕通知,在目标方法完成先后作加强处理,环绕通知是最重要的通知类型,像事务,日志等都是环绕通知,注意编程中核心是一个ProceedingJoinPoint
三、常见问题
一、实现AOP的方式有哪些?
二、实现加强的方法有那些?
三、在肯定好须要加强的方法以后,切入点的定位是如何完成的
四、使用@Aspect对SSM进行切入,统计运行时间。
4.解决方案
1):实现AOP的方式有哪些? 在sring里面进行aop操做,使用aspectJ(AspectJ是一种扩展Java)来实现。aspectJ自己是一个单独的面向切面的框架,里面定义了AOP语法,不是spring的一部分,和spring协同完成springAOP的操做,使用aspectJ来实现springAOP的操做有两种方式 1:继承的类的方式(不推荐) 2:基于aspectJ的xml文件 3.基于aspectJ注解
2):实现加强的方法有那些?
织入 引入 3):在肯定好须要加强的方法以后,切入点的定位是如何完成的 能够用execution表达式来解决(经常使用) 也能够用xml配置,使用RegexpMethodPointcutAdvisor,来定义切点。 1.execution(* com.aop.add(..)) 2.匹配全部save开头的方法:execution(* save*(..)) 4):使用@Aspect对SSM进行切入,统计运行时间。 在编码实战的时候讲讲。
5.编码实战
基于xml配置文件配置
须要建立aop对象,设置切入点、加强类、方法等。
基于注解方式配置文件
<context:component-scan base-package="anno"/> <aop:aspectj-autoproxy />
注意这里尽量使用闭合标签,不要使用,不然没法正常切入<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
这里上传一个简单的基于注解方式的aop demo
applicationContext.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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd"> <context:component-scan base-package="anno"/> <aop:aspectj-autoproxy /> </beans> UserService.java package anno; import org.springframework.stereotype.Service; @Service public class UserService { public void add(){ System.out.println("UserService add()"); } public boolean delete(){ System.out.println("UserService delete()"); return true; } public void edit(){ System.out.println("UserService edit()"); int i = 5/0; } } Operator.java package anno; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.*; import org.springframework.stereotype.Component; @Component @Aspect public class Operator { @Pointcut("execution(* anno..*.*(..))") public void pointCut(){} @Before("pointCut()") public void doBefore(JoinPoint joinPoint){ System.out.println("AOP Before Advice..."); } @After("pointCut()") public void doAfter(JoinPoint joinPoint){ System.out.println("AOP After Advice..."); } @AfterReturning(pointcut="pointCut()",returning="returnVal") public void afterReturn(JoinPoint joinPoint,Object returnVal){ System.out.println("AOP AfterReturning Advice:" + returnVal); } @AfterThrowing(pointcut="pointCut()",throwing="error") public void afterThrowing(JoinPoint joinPoint,Throwable error){ System.out.println("AOP AfterThrowing Advice..." + error); System.out.println("AfterThrowing..."); } @Around("pointCut()") public void around(ProceedingJoinPoint pjp){ System.out.println("AOP Aronud before..."); try { pjp.proceed(); } catch (Throwable e) { e.printStackTrace(); } System.out.println("AOP Aronud after..."); } } Test.java package anno; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Test { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:applicationContext.xml"); UserService userService = (UserService) ctx.getBean("userService"); userService.add(); } }
运行结果
扩展思考
一、 基于注解与基于配置文件的优缺点.
优势: 注解能减小配置的工做,并且配置信息和JAVA代码放在一块儿,有助于加强程序的内聚性。相对于XML配置文件进行配置文件和程序文件的切换,用注解方式,能提升开发的连贯性,和提成开发效率。 缺点: 程序复杂的话,仍是使用xml配置文件的方式,这样可读性和可维护性比较强。
https://www.cnblogs.com/liuru...
https://www.cnblogs.com/hongw...
https://blog.csdn.net/zghwaic...
更多讨论
一、 基于注解与基于配置文件的优缺点有哪些?
优势: 注解能减小配置的工做,并且配置信息和JAVA代码放在一块儿,有助于加强程序的内聚性。相对于XML配置文件进行配置文件和程序文件的切换,用注解方式,能提升开发的连贯性,和提成开发效率。 缺点: 程序复杂的话,仍是使用xml配置文件的方式,这样可读性和可维护性比较强。
二、实现AOP的方式有哪些?
在sring里面进行aop操做,使用aspectJ(AspectJ是一种扩展Java)来实现。aspectJ自己是一个单独的面向切面的框架,里面定义了AOP语法,不是spring的一部分,和spring协同完成springAOP的操做,使用aspectJ来实现springAOP的操做有两种方式 1:继承的类的方式(不推荐) 2:基于aspectJ的xml文件 3.基于aspectJ注解
三、实现加强的方法有那些?
织入 引入
两种方式
今天的分享就到这里啦,欢迎你们点赞、转发、留言、拍砖~