24.Spring中AOP的概念:
可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。
从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。
这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来的效果
(1).连接点:可能需要注入切面的地方,如方法前后,类、变量初始化前后。
(2).切点:需要做某些处理(如打印日志、处理缓存等等)的连接点。
(3).通知:切点处所执行的逻辑。
(4).切面:通知与切入点的组合。
(5).引入:为某一个类型声明额外的方法或者属性。
(6).目标对象:被通知的源对象。
(7).AOP代理:由AOP框架创建的代理对象。
(8).织入:将切面和目标对象进行连接形成代理对象的过程。
AOP分为静态AOP和动态AOP。
静态AOP是指AspectJ实现的AOP,他是将切面代码直接编译到Java类文件中。
动态AOP是指将切面代码进行动态织入实现的AOP。
Spring的AOP为动态AOP,实现的技术为: JDK提供的动态代理技术 和 CGLIB(动态字节码增强技术) 。尽管实现技术不一样,但 都是基于代理模式 , 都是生成一个代理对象 。
在定义切面的时候指定切点位置的方式:
(1).// 匹配所有以set开头的公有方法
@Pointcut(“execution(public * set*(…))”)
(2).// 匹配 com.pengjunlee.service 包及其子包下的类的所有方法
@Pointcut(“execution(* com.pengjunlee.service….(…))”)
(3).匹配注解出现的地方:
@Pointcut("@annotation(c)")
25.springMVC中拦截器的使用
(1).定义拦截器类:
第一种方式是要定义的Interceptor类要实现了Spring的HandlerInterceptor 接口
第二种方式是继承实现了HandlerInterceptor接口的类,比如Spring已经提供的实现了HandlerInterceptor接口的抽象类HandlerInterceptorAdapter
HandlerInterceptor 接口中定义了三个方法,我们就是通过这三个方法来对用户的请求进行拦截处理的。
preHandle(): 这个方法在业务处理器处理请求之前被调用,SpringMVC 中的Interceptor 是链式的调用的,在一个应用中或者说是在一个请求中可以同时存在多个Interceptor 。每个Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是Interceptor 中的preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求的一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值Boolean 类型的,当它返回为false 时,表示请求结束,后续的Interceptor 和Controller 都不会再执行;当返回值为true 时就会继续调用下一个Interceptor 的preHandle 方法,如果已经是最后一个Interceptor 的时候就会是调用当前请求的Controller 方法。
postHandle():这个方法在当前请求进行处理之后,也就是Controller 方法调用之后执行,但是它会在DispatcherServlet 进行视图返回渲染之前被调用,所以我们可以在这个方法中对Controller 处理之后的ModelAndView 对象进行操作。postHandle 方法被调用的方向跟preHandle 是相反的,也就是说先声明的Interceptor 的postHandle 方法反而会后执行。
afterCompletion():该方法也是需要当前对应的Interceptor 的preHandle 方法的返回值为true 时才会执行。顾名思义,该方法将在整个请求结束之后,也就是在DispatcherServlet 渲染了对应的视图之后执行。这个方法的主要作用是用于进行资源清理工作的。
(2).在XML文件中配置拦截器:
<mvc:interceptors>
<mvc:interceptor>
<!--
/**的意思是所有文件夹及里面的子文件夹
/*是所有文件夹,不含子文件夹
/是web项目的根目录
-->
<mvc:mapping path="/**" />
<!-- 需排除拦截的地址 -->
<!-- <mvc:exclude-mapping path="/userController/login"/> -->
<bean id="commonInterceptor" class="org.shop.interceptor.CommonInterceptor"></bean> <!--这个类就是我们自定义的Interceptor -->
</mvc:interceptor>
<!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>`
26.springBoot框架中使用拦截器:
(1).实现拦截器:实现方式与springMVC相同。
(2).注册拦截器:实现拦截器后还需要将拦截器注册到spring容器中,可以通过implements WebMvcConfigurer,覆盖其addInterceptors(InterceptorRegistry registry)方法。记得把Bean注册到Spring容器中,可以选择@Component 或者 @Configuration。拦截器的执行顺序和配置顺序有关系,即先配置顺序就在前
(3).拦截器的工作流程:
一个拦截器,只有preHandle方法返回true,postHandle、afterCompletion才有可能被执行;如果preHandle方法返回false,则该拦截器的postHandle、afterCompletion必然不会被执行。拦截器不是Filter,却实现了Filter的功能,其原理在于:
所有的拦截器(Interceptor)和处理器(Handler)都注册在HandlerMapping中。
Spring MVC中所有的请求都是由DispatcherServlet分发的。
当请求进入DispatcherServlet.doDispatch()时候,首先会得到处理该请求的Handler(即Controller中对应的方法)以及所有拦截该请求的拦截器。拦截器就是在这里被调用开始工作的。
27.JDK的动态代理
通过Proxy.newProxyInstance()返回的代理对象实现,Proxy.newProxyInstance()有三个参数,返回Object:
(1).ClassLoade loader: 用哪个类加载器去加载代理对象。
(2).Class<?>[] interfaces:动态代理类需要实现的接口。
(3).InvocationHandler h:动态代理方法在执行时,会调用h里面的invoke方法去执行。
invoke方法有三个参数,返回Object:
(1).Object proxy:代理对象,newProxyInstance方法的返回对象
(2).Method method:需要调用的方法,
(3).Object[] args:方法中的参数。
28.互联网软件架构原则REST:表现层状态转换
访问一个资源需要客户端和服务端进行一定的交互,势必设计数据和状态的变化。HTTP协议是一种无状态协议,因此,所有的状态都保存在服务端,如果客户端想要操作服务端,必须通过某种手段,这种手段便是HTTP协议里的几种操作方式,如GET、POST、PUT、DELETE。RESTful风格其中一个思想是通过HTTP请求对应的GET、POST、PUT、DELETE方法,来完成对应的curd操作。
29.volatile关键字
确保一个变量的更新以可预见的方式告知其他线程,当一个域声明为volatile类型后,编译器运行时会监视这个变量,它是共享的,对他的操作不会与其他内存操作一起呗重排序。volatile变量不会缓存在寄存器或者缓存在对其他处理器隐藏的地方。所以,读一个volatile类型的变量时,总会返回由某一线程所写入的最新值。