Spring的AOP配置
- 格式:doc
- 大小:90.00 KB
- 文档页数:14
SpringBoot使⽤过滤器、拦截器、切⾯(AOP),及其之间的区别和执⾏顺序先上代码,下⾯的demo中包含多个拦截器、过滤器,以及切⾯的前置通知/后置通知/环绕通知:下⾯总结⼀下相关原理:⾸先了解⼀下SpringMVC的执⾏流程具体流程如下1. ⽤户发起请求到前端控制器(Controller)2. 前端控制器没有处理业务逻辑的能⼒,需要找到具体的模型对象处理(Handler),到处理器映射器(HandlerMapping)中查找Handler对象(Model)。
3. HandlerMapping返回执⾏链,包含了2部分内容:① Handler对象、②拦截器数组4. 前端处理器通过处理器适配器包装后执⾏Handler对象。
5. 处理业务逻辑。
6. Handler处理完业务逻辑,返回ModelAndView对象,其中view是视图名称,不是真正的视图对象。
7. 将ModelAndView返回给前端控制器。
8. 视图解析器(ViewResolver)返回真正的视图对象(View)。
9. (此时前端控制器中既有视图⼜有Model对象数据)前端控制器根据模型数据和视图对象,进⾏视图渲染。
10. 返回渲染后的视图(html/json/xml)返回。
11. 给⽤户产⽣响应。
核⼼就是DispatcherServlet核⼼控制器,我们看源码可知道DispatcherServlet是Servlet的⼦类下⾯⽤⼀张图说⼀下过滤器、Servlet容器、拦截器、AOP、Controller之间的关系然后具体执⾏流程如下:拦截器和过滤器的区别1、拦截器不依赖与servlet容器是SpringMVC⾃带的,过滤器依赖于Servlet容器。
2、拦截器是基于java的反射机制的,⽽过滤器是基于函数回调。
3、拦截器只能对action请求起作⽤,⽽过滤器则可以对⼏乎所有的请求起作⽤。
4、拦截器可以访问controller上下⽂、值栈⾥的对象,⽽过滤器不能访问。
基于SpringBootAOP与自定义注解转义字典值要基于SpringBoot、AOP和自定义注解来转义字典值,可以按照以下步骤进行:1.创建一个字典表,存储字典值和对应的转义值。
例如,可以创建一个数据库表或者在配置文件中定义一个字典映射关系。
4.在切面方法中,获取需要转义的字段的值,然后根据字典表中的映射关系,找到对应的转义值,并将转义值设置回字段。
5.在需要使用转义值的地方,直接使用被转义后的字段值即可。
下面是一个简单的示例代码:1.创建字典表,例如在配置文件中定义:```yamldict.mapping:gender:0:男1:女``````javaString value( default "";```3.创建AOP切面类:```javapublic class DictTransAspectprivate DictMapping dictMapping;public Object dictTrans(ProceedingJoinPoint joinPoint) throws ThrowableObject result = joinPoint.proceed(;//获取被标记的字段或方法Field field =ReflectionUtils.findField(joinPoint.getTarget(.getClass(, ((MethodSignature) joinPoint.getSignature().getName();DictTrans dictTrans = field.getAnnotation(DictTrans.class);if (dictTrans != null)//获取字段值Object value = field.get(joinPoint.getTarget();//获取字段的字典映射关系Map<String, String> mapping =dictMapping.getMapping(dictTrans.value();//根据字典映射关系转义字段值String transValue = mapping.get(value.toString();//设置转义值回字段field.set(joinPoint.getTarget(, transValue);}return result;}``````javapublic class Userprivate Integer gender;// getter and setter```5.在业务中使用转义后的字段值:```javapublic class UserService// 注入 UserMapper 或者其他数据访问层public User getUserById(String id)User user = userMapper.findById(id);System.out.println(user.getGender(); // 输出转义后的值,例如输出 "男"return user;}```这样,就实现了基于 SpringBoot、AOP 和自定义注解来转义字典值的功能。
SpringAOP的原理和应用场景SpringAOP(Aspect-Oriented Programming)是Spring框架中的一个重要组成部分,它提供了一种通过预定义的方式,将横切关注点(Cross-cutting Concerns)与业务逻辑进行解耦的机制。
本文将介绍SpringAOP的原理及其在实际应用场景中的应用。
一、SpringAOP的原理SpringAOP基于代理模式(Proxy Pattern)实现。
在SpringAOP中,通过生成与原始类(被代理类)具有相同接口的代理类,将横切逻辑编织到业务逻辑中。
在运行时,当调用代理类的方法时,会在方法执行前、后或异常抛出时插入相应的横切逻辑代码。
具体而言,SpringAOP使用了以下几个核心概念:1. 切面(Aspect):切面是横切逻辑的模块化单元,它包含了一组通知(Advice)和切点(Pointcut)。
2. 通知(Advice):通知定义了实际的横切逻辑代码,并规定了何时执行该代码。
SpringAOP提供了五种类型的通知:前置通知(Before)、后置通知(After)、返回通知(After-returning)、异常通知(After-throwing)和环绕通知(Around)。
3. 切点(Pointcut):切点指定了在哪些连接点(Join Point)上执行通知。
连接点可以是方法调用、属性访问等程序执行的点。
4. 连接点(Join Point):连接点是程序执行过程中的一个特定点,如方法调用前、方法调用后等。
通知通过切点来选择连接点。
5. 织入(Weaving):织入是将切面应用到目标对象,并创建代理对象的过程。
织入可以在编译时、类加载时或运行时进行。
二、SpringAOP的应用场景SpringAOP可应用于各种场景,用于解决跨越多个模块或类的横切关注点问题。
以下是一些常见的SpringAOP应用场景:1. 日志记录:通过在关键方法的前后插入日志代码,实现对系统运行状态的监控和记录。
SpringAOP⽰例与实现原理总结——传统springaop、基于切⾯注⼊、基于@Asp。
⼀、代码实践1)经典的Spring Aop经典的spring aop,是基于动态代理技术的。
实现⽅式上,最常⽤的是实现MethodInterceptor接⼝来提供环绕通知,创建若⼲代理,然后使⽤ProxyBeanFactory配置⼯⼚bean,⽣成拦截器链,完成拦截。
⽰例如下:1package demo.spring;23import org.aopalliance.intercept.MethodInterceptor;4import org.aopalliance.intercept.MethodInvocation;5import org.junit.Test;6import org.junit.runner.RunWith;7import org.springframework.beans.factory.annotation.Autowired;8import org.springframework.test.context.ContextConfiguration;9import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;1011 @RunWith(SpringJUnit4ClassRunner.class)12 @ContextConfiguration("classpath:spring-config.xml")13public class TraditionalSpringAopDemo {14 @Autowired15private Service proxy;1617 @Test18public void test() {19 proxy.execute("hello world!");20 }21 }2223interface Service {24void execute(String str);25 }2627class ServiceImpl implements Service {28 @Override29public void execute(String str) {30 System.out.println("execute invoke: " + str);31 }32 }3334class Interceptor1 implements MethodInterceptor {35 @Override36public Object invoke(MethodInvocation methodInvocation) throws Throwable {37 System.out.println("interceptor1,before invoke");38 Object ret = methodInvocation.proceed();39 System.out.println("interceptor1,after invoke");40return ret;41 }42 }4344class Interceptor2 implements MethodInterceptor {45 @Override46public Object invoke(MethodInvocation methodInvocation) throws Throwable {47 System.out.println("interceptor2,before invoke");48 Object ret = methodInvocation.proceed();49 System.out.println("interceptor2,after invoke");50return ret;51 }52 }xml⽂件配置:1<?xml version="1.0" encoding="UTF-8"?>2<beans xmlns="/schema/beans"3 xmlns:xsi="/2001/XMLSchema-instance"4 xmlns:context="/schema/context"5 xmlns:aop="/schema/aop"6 xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd /schema/context /schema/context/sprin 78<context:component-scan base-package="demo.spring"/>910<bean class="demo.spring.ServiceImpl" id="service"></bean>11<bean class="demo.spring.Interceptor1" id="interceptor1"></bean>12<bean class="demo.spring.Interceptor2" id="interceptor2"></bean>13<bean class="org.springframework.aop.framework.ProxyFactoryBean" id="proxy">14<property name="target" ref="service"/>15<property name="interceptorNames">16<list>17<value>interceptor1</value>18<value>interceptor2</value>19</list>20</property>21</bean>22</beans>结果:interceptor1,before invokeinterceptor2,before invokeexecute invoke: hello world!interceptor2,after invokeinterceptor1,after invoke可以看到拦截链的执⾏过程与拦截器顺序的关系。
SpringAOP:@Before、@After的JavaConfig写法⽹络上关于Spring AOP的范例⼤都是使⽤xml作配置⽂件,见此特地写⼀些JavaConfig的范例,既为加深理解,亦为加强记忆。
如需引⽤或转载的同学,请注明来源。
使⽤Spring AOP,要成功运⾏起代码,只⽤Spring提供给开发者的jar包是不够的,请额外上⽹下载两个jar包导⼊项⽬中:aopalliance.jaraspectjweaver.jar。
由于我使⽤IDEA_U创建的spring项⽬,aopalliance.jar是Maven⾃动下载的,⽽ aspectjweaver.jar 则需要另外下载,然后⽤解压软件打开,解压出 aspectjweaver.jar先写⼀个接⼝:@Componentpublic interface Person {void say();void run();}再写两个实现类:@Component@Qualifier("adults")public class Adults implements Person {private String classname = "adults";@Overridepublic void say() {System.out.println("I am " + classname + " , I like acid rock.");}@Overridepublic void run() {System.out.println("I am " + classname + " , I like long-distance");}}@Component@Qualifier("children")public class Children implements Person {private String classname = "children";@Overridepublic void say() {System.out.println("We are " + classname + " , we like nursery rhymes.");}@Overridepublic void run() {System.out.println("We are " + classname + " , we like running around.");}}然后写⼀个切⾯,这也是⼀个类:@Component@Aspect //声明这是⼀个切⾯。
public class Common {public void execute(String username,String password){System.out.println("------------------普通类----------------");}}2.写一个切面类,用于合法性校验和日志添加:package com.spring.aop;public class Check {public void checkV alidity(){System.out.println("------------------验证合法性----------------");}public void addLog(JoinPoint j){System.out.println("------------------添加日志----------------");Object obj[] = j.getArgs();for(Object o :obj){System.out.println(o);}System.out.println("========checkSecurity=="+j.getSignature().getName());//这个是获得方法名}}3.配置AOP,使用XML 方式:(注意红色标志的内容注意红色标志的内容)<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="/schema/aop"xsi:schemaLocation="/schema/beans/schema/beans/spring-beans-2.5.xsd/schema/aop/schema/aop/spring-aop-2.5.xsd"><bean id="common" class="mon"/><bean id="check" class="com.spring.aop.Check"/><aop:config><aop:aspect id="myAop" ref="check"><aop:pointcut id="target" expression="execution(*mon.execute(..))"/><aop:before method="checkValidity" pointcut-ref="target"/><aop:after method="addLog" pointcut-ref="target"/></aop:aspect></aop:config></beans>注意:execution(* com.spring.aop.*.*(..))"/ 这样写应该就可以了这是com.aptech.jb.epet.dao.hibimpl 包下所有的类的所有方法。
AOP切面的使用以及如何在通知上获取切入方法的注解和参数AOP(面向切面编程)是一种编程思想,它将通用横切逻辑(例如日志记录、事务管理、权限控制等)从业务逻辑中分离出来,使得代码更加模块化、可维护和可重用。
AOP通过使用切面(Aspect)来实现这种分离过程,切面可以被应用到多个对象上,从而实现横切逻辑的复用。
在Java中,可以使用AspectJ或Spring AOP等框架来实现AOP。
这些框架都提供了一种方式来声明切面,并将其应用到目标方法上。
通常,切面可以通过注解或配置文件进行声明。
本文将以Spring AOP为例,介绍AOP切面的使用,并说明如何在通知上获取切入方法的注解和参数。
首先,我们需要定义一个切面类(Aspect),用于描述横切逻辑。
切面类通常包含多个通知(Advice),每个通知表示了在目标方法的不同位置执行的操作。
常用的通知类型有:1. 前置通知(Before):在目标方法执行之前执行的操作。
2. 后置通知(After):在目标方法执行之后(包括异常返回)执行的操作。
3. 返回通知(After Returning):在目标方法正常返回之后执行的操作。
4. 异常通知(After Throwing):在目标方法抛出异常之后执行的操作。
5. 环绕通知(Around):在目标方法执行之前和之后都执行的操作。
下面是一个简单的切面类的示例:```javapublic class LoggingAspectpublic void beforeMethod(JoinPoint joinPoint)MethodSignature signature = (MethodSignature)joinPoint.getSignature(;Method method = signature.getMethod(;Loggable loggable = method.getAnnotation(Loggable.class);String message = loggable.value(;//打印日志信息System.out.println("Loggable message: " + message);}public Object aroundMethod(ProceedingJoinPoint joinPoint) throws ThrowableMethodSignature signature = (MethodSignature)joinPoint.getSignature(;Method method = signature.getMethod(;Loggable loggable = method.getAnnotation(Loggable.class);String message = loggable.value(;//执行目标方法前的操作System.out.println("Before executing method: " +method.getName();//执行目标方法Object result = joinPoint.proceed(;//执行目标方法后的操作System.out.println("After executing method: " +method.getName();return result;}```在切面类中,我们通过`JoinPoint`参数来获取切入点的相关信息,如目标方法的签名(通过`getSignature(`方法获取)、方法的注解(通过`getAnnotation(`方法获取)等。
Spring中IOC和AOP的深⼊讲解前⾔Spring是⼀个开源框架,Spring是于2003 年兴起的⼀个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2EE Development and Design中阐述的部分理念和原型衍⽣⽽来。
它是为了解决企业应⽤开发的复杂性⽽创建的。
Spring使⽤基本的JavaBean来完成以前只可能由EJB完成的事情。
然⽽,Spring的⽤途不仅限于服务器端的开发。
从简单性、可测试性和松耦合的⾓度⽽⾔,任何Java应⽤都可以从Spring中受益。
简单来说,Spring是⼀个轻量级的控制反转(IoC)和⾯向切⾯(AOP)的容器框架。
这篇⽂章主要讲 Spring 中的⼏个点,Spring 中的 IOC,AOP,下⼀篇说说 Spring 中的事务操作,注解和 XML 配置。
Spring 简介Spring 是⼀个开源的轻量级的企业级框架,其核⼼是反转控制 (IoC) 和⾯向切⾯ (AOP) 的容器框架。
我们可以把 Spring 看成是对象的容器,容器中可以包含很多对象,所以 Spring 有很多强⼤的功能。
⼀句话,Spring 是项⽬中对象的管家,负责管理项⽬中⽤到的所有对象。
所以在项⽬三层架构中,Spring 不属于某⼀特定层。
Spring 的 Hello World想要构建⼀个 Spring 的⼊门程序,我们需要导⼊ 4 个核⼼包和 2 个辅助包,创建⼀个实体类,最主要的是编写核⼼配置⽂件,applicationContext.xml 放在 src 下。
最后写⼀个测试类即可。
此时在测试类中我们不需要在使⽤ new 关键字去创建对象了。
这也正是 Spring 的作⽤所在,会⾃动给我创建对象。
上图展⽰的就是最基本的演⽰,也是很容易就理解了,配置⽂件中配置了 user 对象,我们通过加载配置⽂件来获取对象从⽽避免了使⽤ new 来创建。
SpringAOP切⾯⽇志Demo配置⽂件⽅式与注解⽅式⼀、配置⽂件⽅式1、配置applicationContext.xml,<bean id="logAopBean"class="mon.aop.LogAop"></bean><aop:config><aop:aspect id="logAspect"ref="logAopBean"><aop:pointcut expression="execution(* com.demo..*(..))" id="allMethod"/><aop:before method="before" pointcut-ref="allMethod" /><aop:after-throwing method="afterThrowing" pointcut-ref="allMethod" /><aop:after-returning method="afterReturn" pointcut-ref="allMethod" /><aop:after method="after" pointcut-ref="allMethod" /></aop:aspect></aop:config>2、⽇志处理类,/*** LogAop.java** Shanghai NTT DATA Synergy Software Co., Ltd. All Rights Reserved.* @author wyl* @date 2016-10-18*/package mon.aop;import ng.JoinPoint;import ng.ProceedingJoinPoint;/*** @author wyl* @Description TODO* @date 2016-10-18**/public class LogAop {public void before(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println("开始执⾏:"+className+"."+methodName+"()⽅法...");}public void afterThrowing(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法抛出了异常...");}public void afterReturn(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法正常执⾏结束...");}public void after(JoinPoint call){String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()最终执⾏步骤(finally)...");}/*//⽤来做环绕通知的⽅法可以第⼀个参数定义为ng.ProceedingJoinPoint类型public Object doAround(ProceedingJoinPoint call) throws Throwable {Object result = null;this.before(call);//相当于前置通知try {result = call.proceed();this.afterReturn(call); //相当于后置通知} catch (Throwable e) {this.afterThrowing(call); //相当于异常抛出后通知throw e;}finally{this.after(call); //相当于最终通知}return result;}*/}⼆、注解⽅式1、配置applicationContext.xml,<bean id="logAspectBean"class="mon.aop.LogAnnotationAspect"></bean> <aop:aspectj-autoproxy/>2、⽇志处理类,/*** LogAnnotationAspect.java** Shanghai NTT DATA Synergy Software Co., Ltd. All Rights Reserved.* @author wyl* @date 2016-10-18*/package mon.aop;import ng.JoinPoint;import ng.ProceedingJoinPoint;import ng.annotation.After;import ng.annotation.AfterReturning;import ng.annotation.AfterThrowing;import ng.annotation.Aspect;import ng.annotation.Before;import ng.annotation.Pointcut;/*** @author wyl* @Description TODO* @date 2016-10-18**/@Aspect //定义切⾯类public class LogAnnotationAspect {@SuppressWarnings("unused")//定义切⼊点,提供⼀个⽅法,这个⽅法的名字就是改切⼊点的id@Pointcut("execution(* com.demo..*(..))")private void allMethod(){}//针对指定的切⼊点表达式选择的切⼊点应⽤前置通知@Before("allMethod()")public void before(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println("开始执⾏:"+className+"."+methodName+"()⽅法...");}//访问命名切⼊点来应⽤后置通知@AfterReturning("allMethod()")public void afterReturn(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法正常执⾏结束...");}//应⽤最终通知@After("allMethod()")public void after(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()最终执⾏步骤(finally)...");}//应⽤异常抛出后通知@AfterThrowing("allMethod()")public void afterThrowing(JoinPoint call) {String className = call.getTarget().getClass().getName();String methodName = call.getSignature().getName();System.out.println(className+"."+methodName+"()⽅法抛出了异常...");}//应⽤周围通知//@Around("allMethod()")public Object doAround(ProceedingJoinPoint call) throws Throwable{Object result = null;this.before(call);//相当于前置通知try {result = call.proceed();this.afterReturn(call); //相当于后置通知} catch (Throwable e) {this.afterThrowing(call); //相当于异常抛出后通知throw e;}finally{this.after(call); //相当于最终通知}return result;}}。
Spring技术内幕——深入解析Spring架构与设计原理(二)AOPAOP联盟定义的AOP体系结构把与AOP相关的概念大致分为了由高到低、从用法到实现的三个层次。
关于这个体系结构,个人的理解是这样的,从上往下,最高层是语言和开发环境,在这个环境中可以看到几个重要的概念:base可以视为待增加对象,或者说目标对象;aspect指切面,通常包含对于base的增加应用;configuration可以看成是一种编织或者说配置,通过在AOP体系中提供这个configuration配置环境,可以把base和aspect结合起来,从而完成切面向目标对象的编织实现。
对Spring平台或者说生态系统来说,AOP是Spring框架的核心功能模块之一。
AOP与IOC容器的结合用法, 为应用开发或者Spring自身功能的扩展都提供了许多方便。
Spring AOP的实现和其他特性的实现一样,十分丰盛,除了可以用法Spring本身提供的AOP实现之外,还封装了业界优秀的AOP解决计划AspectJ来让应用用法。
在这里,主要对Spring自身的AOP实现原理做一些解析;在这个AOP实现中,Spring 充分利用了IOC容器Proxy代理对象以及AOP拦截器的功能特性,通过这些对AOP基本功能的封装机制,为用户提供了AOP的实现框架。
所以,要了解这些AOP的基本实现,需要我们对Java 的Proxy机制有一些基本了解。
AOP实现的基本线索 AOP实现中,可以看到三个主要的步骤,一个是代理对象的生成,然后是拦截器的作用,然后是Aspect编织的实现。
AOP框架的丰盛,很大程度体现在这三个详细实现中,所具有的丰盛的技术挑选,以及如何实现与IOC容器的无缝结合。
究竟这也是一个十分核心的模块,需要满足不同的应用需求带来的解决计划需求。
在Spring AOP的实现原理中,我们主要举ProxyFactoryBean的实现作为例子和实现的基本线索举行分析;很大一个缘由,是由于ProxyFactoryBean是在Spring IoC环境中,创建AOP应用的最底层办法,从中,可以看到一条实现AOP的基本线索。
Spring-boot配置Aop获取controller⾥的request中的参数以及其返回值⽰例:当前url:http://localhost:8080/CarsiLogCenter_new/idpstat.jsp?action=idp.sptopnrequest.getRequestURL() http://localhost:8080/CarsiLogCenter_new/idpstat.jsprequest.getRequestURI() /CarsiLogCenter_new/idpstat.jsprequest.getContextPath()/CarsiLogCenter_newrequest.getServletPath() /idpstat.jsprequest.getQueryString() action=idp.sptopnpublic static String getLastAccessUrl(HttpServletRequest request) {StringBuffer requestURL = request.getRequestURI();String queryString = request.getQueryString();if (queryString == null) {return requestURL.toString();}return requestURL + "?" + queryString;}1、request.getRequestURL()返回的是完整的url,包括Http协议,端⼝号,servlet名字和映射路径,但它不包含请求参数。
2、request.getRequestURI()得到的是request URL的部分值,并且web容器没有decode过的3、request.getContextPath()返回 the context of the request.4、request.getServletPath()返回调⽤servlet的部分url.5、request.getQueryString()返回url路径后⾯的查询字符串⾸先在你的Maven的pom⽂件⾥加⼊aop的依赖:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>在spring boot⾥⾯⼀切配置都是很简单的,下⾯为我所有被请求到的controller加上Aop的功能吧,看码:import javax.servlet.http.HttpServletRequest;import ng.ProceedingJoinPoint;import ng.annotation.Around;import ng.annotation.Aspect;import ng.annotation.Pointcut;import org.springframework.context.annotation.Configuration;import org.springframework.web.context.request.RequestAttributes;import org.springframework.web.context.request.RequestContextHolder;import org.springframework.web.context.request.ServletRequestAttributes;import com.google.gson.Gson;import org.slf4j.Logger;import org.slf4j.LoggerFactory;;@Aspect //定义⼀个切⾯@Configurationpublic class LogRecordAspect {private static final Logger logger = LoggerFactory.getLogger(UserInterceptor.class);// 定义切点Pointcut@Pointcut("execution(* com.jiaobuchong.web.*Controller.*(..))")public void excudeService() {}@Around("excudeService()")public Object doAround(ProceedingJoinPoint pjp) throws Throwable {RequestAttributes ra = RequestContextHolder.getRequestAttributes();ServletRequestAttributes sra = (ServletRequestAttributes) ra;HttpServletRequest request = sra.getRequest();String url = request.getRequestURL().toString();String method = request.getMethod();String uri = request.getRequestURI();String queryString = request.getQueryString();("请求开始, 各个参数, url: {}, method: {}, uri: {}, params: {}", url, method, uri, queryString);// result的值就是被拦截⽅法的返回值Object result = pjp.proceed();Gson gson = new Gson();("请求结束,controller的返回值是 " + gson.toJson(result));return result;}}。
详解SpringBootAOP拦截器(Aspect注解⽅式)常⽤⽤于实现拦截的有:Filter、HandlerInterceptor、MethodInterceptor第⼀种Filter属于Servlet提供的,后两者是spring提供的,HandlerInterceptor属于Spring MVC项⽬提供的,⽤来拦截请求,在MethodInterceptor之前执⾏。
实现⼀个HandlerInterceptor可以实现接⼝HandlerInterceptor,也可以继承HandlerInterceptorAdapter类,两种⽅法⼀样。
这个不在本⽂范围,具体使⽤之前已经写过SpringBoot的(SpringMVC的使⽤⼀样,区别只是配置)MethodInterceptor是AOP项⽬中的拦截器,它拦截的⽬标是⽅法,即使不是Controller中的⽅法。
实现MethodInterceptor拦截器⼤致也分为两种,⼀种是实现MethodInterceptor接⼝,另⼀种利⽤Aspect的注解或配置。
关于实现MethodInterceptor接⼝的这种⽅法,还需要在配置⽂件中做配置,在SpringMVC中使⽤还可以,在SpringBoot中使⽤起来似乎没有那么⽅便。
本⽂主要还是说Aspect注解⽅式,个⼈觉得这种⽅法才⽐较灵活,与配置与⼯程整个代码都没有耦合(你添加⼀个类,做⼏个注解就可以⽤了,⽆需在其他地⽅再做什么),更易应⽤。
⾸先为你的SpringBoot项⽬添加maven依赖,让其⽀持aop(其实就是⾃动引⼊aop需要的⼀些jar)在pom.xml中添加依赖:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency>然后创建Aspect测试类:package com.shanhy.sboot.aop;import ng.JoinPoint;import ng.annotation.After;import ng.annotation.Aspect;import ng.annotation.Before;import org.springframework.core.annotation.Order;import ponent;@Aspect // FOR AOP@Order(-99) // 控制多个Aspect的执⾏顺序,越⼩越先执⾏@Componentpublic class TestAspect {@Before("@annotation(test)")// 拦截被TestAnnotation注解的⽅法;如果你需要拦截指定package指定规则名称的⽅法,可以使⽤表达式execution(...),具体百度⼀下资料⼀⼤堆 public void beforeTest(JoinPoint point, TestAnnotation test) throws Throwable {System.out.println("beforeTest:" + ());}@After("@annotation(test)")public void afterTest(JoinPoint point, TestAnnotation test) {System.out.println("afterTest:" + ());}}这样就完成了,然后创建⼀个Controller验证⼀下:@RestController@RequestMapping("/test")public class TestController {@TestAnnotation(name="abc")@RequestMapping("/show")public String show() {return "OK";}@RequestMapping("/show2")public String show2() {return "OK2";}}此时我们访问show请求,就会被拦截,控制台会打印输出。
Spring框架——AOP(⾯向切⾯编程)详解1 AOP概述●AOP(Aspect-Oriented Programming,⾯向切⾯编程):是⼀种新的⽅法论,是对传统 OOP(Object-Oriented Programming,⾯向对象编程)的补充。
●AOP编程操作的主要对象是切⾯(aspect),⽽切⾯模块化横切关注点。
●在应⽤AOP编程时,仍然需要定义公共功能,但可以明确的定义这个功能应⽤在哪⾥,以什么⽅式应⽤,并且不必修改受影响的类。
这样⼀来横切关注点就被模块化到特殊的类⾥——这样的类我们通常称之为“切⾯”。
●AOP的好处:○每个事物逻辑位于⼀个位置,代码不分散,便于维护和升级○业务模块更简洁,只包含核⼼业务代码2 AOP术语2.1 横切关注点 从每个⽅法中抽取出来的同⼀类⾮核⼼业务。
(抽离到⽅法中处理⾮核⼼业务)2.2 切⾯(Aspect) 封装横切关注点信息的类,每个关注点体现为⼀个通知⽅法。
2.3 通知(Advice) 切⾯必须要完成的各个具体⼯作2.4 ⽬标(Target) 被通知的对象2.5 代理(Proxy) 向⽬标对象应⽤通知之后创建的代理对象2.6 连接点(Joinpoint) 横切关注点在程序代码中的具体体现,对应程序执⾏的某个特定位置。
例如:类某个⽅法调⽤前、调⽤后、⽅法捕获到异常后等。
在应⽤程序中可以使⽤横纵两个坐标来定位⼀个具体的连接点:2.7 切⼊点(pointcut): 定位连接点的⽅式。
每个类的⽅法中都包含多个连接点,所以连接点是类中客观存在的事物。
如果把连接点看作数据库中的记录,那么切⼊点就是查询条件——AOP可以通过切⼊点定位到特定的连接点。
切点通过org.springframework.aop.Pointcut 接⼝进⾏描述,它使⽤类和⽅法作为连接点的查询条件。
3 AspectJ3.1 简介AspectJ:Java社区⾥最完整最流⾏的AOP框架。
Spring AOPSpring 是由多个部分组成,包括AOP、DAO、Conetxt、Web、MVC,并且他们都已IoC 容器为基础。
Spring 这么多功能都是由于其IoC 容器的特性,实现了对多种框架的集成,但 AOP 是个例外,它不是对某个框架的集成,而是提供了面向方面编程的功能,你可以自由选择是否使用AOP。
AOP 提供了强大的中间件解决方案,这使得IoC 容器更加完善。
我们可以把AOP 看做是 Sping 的一种增强,它使得 Spring 可以不需要 EJB 就能够提供声明式事务管理,或者也可以使用Spring AOP 框架的全部功能来实现自己定义的切面。
AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。
Spring AOP的核心设计思想:代理模式AOP常用专业术语:①方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。
事务管理是J2EE应用中一个很好的横切关注点例子。
方面用Spring的Advisor或拦截器实现。
②连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。
③通知(Advice):在特定的连接点,AOP框架执行的动作。
各种类型的通知包括“around”、“before”和“throws”通知。
通知类型将在下面讨论。
许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。
④切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。
Spring系列之AOP实现的两种⽅式Spring只⽀持XML⽅式⽽没有实现注解的⽅式(也叫AspectJ⽅式)的AOP,所以要使⽤@Aspect注解,只能引⼊AspectJ相关的 jar 包:aopalliance-1.0.jar 和 aspectjweaver.jarSpring的配置⽂件 applicationContext.xml 中引⼊context、aop对应的命名空间;配置⾃动扫描的包,同时使切⾯类中相关⽅法中的注解⽣效,需⾃动地为匹配到的⽅法所在的类⽣成代理对象。
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="/schema/beans"xmlns:xsi="/2001/XMLSchema-instance"xmlns:aop="/schema/aop"xmlns:context="/schema/context"xsi:schemaLocation="/schema/beans /schema/beans/spring-beans.xsd/schema/aop /schema/aop/spring-aop-4.0.xsd/schema/context /schema/context/spring-context-4.0.xsd"><!-- 配置⾃动扫描的包 --><context:component-scan base-package="com.qcc.beans.aop"></context:component-scan><!-- ⾃动为切⾯⽅法中匹配的⽅法所在的类⽣成代理对象。
--><aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>AOP常⽤的实现⽅式有两种,1、采⽤声明的⽅式来实现(基于XML),2、是采⽤注解的⽅式来实现(基于AspectJ)。
ioc和aop底层实现原理IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)是Spring框架的核心特性,它们在底层实现原理上有各自的特点。
1. IoC原理:IoC是Spring框架的核心概念之一,其基本原理是将对象的创建、初始化、销毁等控制权交给Spring容器来管理,而不再由开发者直接操作。
这样,开发者只需要关注业务逻辑,而不需要关注对象的创建和销毁等细节。
在Spring中,IoC是通过依赖注入(Dependency Injection)实现的。
依赖注入有两种方式:构造器注入:通过构造器的方式将依赖注入到对象中。
属性注入:通过Setter方法或直接赋值的方式将依赖注入到对象中。
Spring容器负责管理Bean的生命周期,包括实例化、属性设置、依赖注入、初始化、销毁等。
在运行时,Spring容器会根据配置文件或注解等方式,自动完成Bean的创建和依赖注入。
2. AOP原理:AOP是Spring框架中的另一个核心概念,它主要关注的是将应用程序中的切面进行抽象和统一管理。
通过AOP,可以将一些通用逻辑(如日志记录、事务管理等)从业务逻辑中分离出来,实现模块化、可复用的代码结构。
在Spring中,AOP通过动态代理实现,其核心组件是切面(Aspect)。
一个切面可以包含多个通知(Advice),每个通知都对应一个特定的方法。
这些通知可以是前置通知(Before)、后置通知(After)、异常抛出通知(AfterThrowing)等。
当一个方法被调用时,Spring会根据配置自动代理该方法,并执行相应的通知。
代理对象会拦截到该方法的调用,并执行相应的通知逻辑。
这样,开发者只需要关注业务逻辑,而不需要手动编写代理代码。
总结:IoC和AOP是Spring框架的核心特性,它们通过不同的方式实现了解耦和模块化。
IoC关注的是对象的创建和生命周期管理,而AOP关注的是将通用逻辑从业务逻辑中分离出来。
aop切面中或获取自定义注解中的参数AOP(面向切面编程)是一种编程思想,它允许开发人员在应用程序的不同层次上插入代码,以便在运行时对其进行拦截和修改。
在AOP中,切面是一组跨越多个类和方法的通用功能,例如日志记录、性能测量、安全性等。
在切面中,我们可以使用自定义注解来传递参数,以便更好地控制切面的行为。
下面是一些有关在AOP切面中或获取自定义注解中的参数的技巧:1. 使用@Around注解@Around注解是Spring AOP中最强大的注解之一。
它允许我们在方法执行之前和之后拦截方法调用,并在必要时修改方法参数和返回值。
在@Around注解中,我们可以使用ProceedingJoinPoint参数访问方法参数和方法签名,并使用它们来执行额外的操作。
2. 使用@Pointcut注解@Pointcut注解用于定义一个切点,即一组匹配的方法或类。
在@Pointcut注解中,我们可以使用自定义注解来指定要匹配的方法或类,并使用它们来定义切点。
例如,我们可以使用@Pointcut注解来定义一个切点,以便在所有被@Loggable注解的方法中添加日志记录。
3. 使用@Aspect注解@Aspect注解用于定义一个切面,即一组跨越多个类和方法的通用功能。
在@Aspect注解中,我们可以使用自定义注解来指定要匹配的方法或类,并使用它们来定义切面。
例如,我们可以使用@Aspect注解来定义一个切面,以便在所有被@Cacheable注解的方法中添加缓存逻辑。
4. 使用@Annotation注解@Annotation注解用于定义一个自定义注解,并将其与切面或切点相关联。
在@Annotation注解中,我们可以使用元注解@Target和@Retention来指定自定义注解的作用域和生命周期,并使用元注解@Inherited来指定自定义注解是否可以被子类继承。
例如,我们可以使用@Annotation注解来定义一个@Loggable注解,并将其与一个日志记录切面相关联。
aop pointcut切点指定controller的方法-回复什么是AOP?AOP(Aspect-Oriented Programming)是一种编程范式,它的目标是将应用程序分为核心业务逻辑和横切关注点。
核心业务逻辑描述了应用程序的主要功能,而横切关注点描述了一些在应用程序中多个模块或组件之间通用的行为,如日志记录、事务管理等。
AOP 的主要思想是通过将横切关注点从核心业务逻辑中分离出来,从而提高代码的模块化和可维护性。
AOP 切面与切点在AOP 中,切面是一个横切关注点,它描述了在应用程序的不同模块或组件中重复出现的行为。
切点是指在应用程序中选择需要应用切面的特定点的过程。
切点可以在代码中通过使用表达式进行指定或通过使用注解进行标记。
在Spring 框架中,我们可以使用AOP 切面和切点来在控制器(Controller)的方法中应用横切关注点。
如何在AOP 中指定Controller 的方法作为切点?要指定Controller 的方法作为AOP 的切点,我们可以使用Spring AOP 和Spring MVC 的一些特性。
以下是一步一步的指南:1. 配置Spring AOP首先,我们需要在Spring 配置文件中启用AOP 功能。
为此,在配置文件中添加以下代码段:xml<aop:aspectj-autoproxy/>这将启用Spring AOP 并自动检测和注册切面。
2. 创建切面现在,我们需要创建一个切面,作为我们在Controller 方法中应用的横切关注点的容器。
在Spring 中,我们可以使用`Aspect` 注解和切点表达式来创建切面。
以下是一个示例:javaAspectpublic class LoggingAspect {Pointcut("execution(* com.example.controller.*.*(..))")public void controllerMethods() {}}在上面的代码中,`Pointcut` 注解指定了切面的切点表达式。
Spring的AOP配置
(2011-04-01 20:38:58)
转载
标签:
分类:SSH框架
spring
aop配置
获取参数
it
1.先写一个普通类:
package com.spring.aop;
public class Common {
public void execute(String username,String password){ System.out.println("------------------普通类----------------");
}
}
2.写一个切面类,用于合法性校验和日志添加:
package com.spring.aop;
public class Check {
public void checkValidity(){
System.out.println("------------------验证合法性----------------"); }
public void addLog(JoinPoint j){
System.out.println("------------------添加日志----------------");
Object obj[] = j.getArgs();
for(Object o :obj){
System.out.println(o);
}
System.out.println("========checkSecurity=="+j.getSignature().getName());//这个是获得方法名
}
}
3.配置AOP,使用XML方式:(注意红色标志的内容)
<?xml version="1.0" encoding="UTF-8"?>
<beans
xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:aop="/schema/aop"
xsi:schemaLocation="/schema/beans
/schema/beans/spring-beans-2.5.xsd
/schema/aop
/schema/aop/spring-aop-2.5.xsd">
<bean id="common" class="mon"/>
<bean id="check" class="com.spring.aop.Check"/>
<aop:config>
<aop:aspect id="myAop" ref="check">
<aop:pointcut id="target" expression="execution(*
mon.execute(..))"/>
<aop:before method="checkValidity" pointcut-ref="target"/>
<aop:after method="addLog" pointcut-ref="target"/>
</aop:aspect>
</aop:config>
注意:
execution(* com.spring.aop.*.*(..))"/
这样写应该就可以了
这是com.aptech.jb.epet.dao.hibimpl 包下所有的类的所有方法。
第一个*代表所有的返回值类型
第二个*代表所有的类
第三个*代表类所有方法
最后一个..代表所有的参数。
4.最后写一个测试:
package com.spring.aop;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Client {
public static void main(String[] args) {
BeanFactory factory=new ClassPathXmlApplicationContext("applicationContext-aop.xml");
Common c=(Common) factory.getBean("common");
c.execute("zhengjunhua","zhengjunhua");
}
}
需要添加三个包:spring-aop.jar , aspectjrt.jar ,aspectjweaver.jar,否则会报错。
输出结果:
------------------验证合法性----------------
------------------普通类----------------
------------------添加日志----------------
zhengjunhua
zhengjunhua
========checkSecurity==execute
Spring AOP配置选项
分类:Spring 2010-08-18 15:39 1108人阅读评论(3) 收藏举报Spring实现动态代理配置是有两种配置文件:
1、xml文件方式;
2、annotation方式(使用AspectJ类库实现的。
)
一、AOP配置annotation方式
(一)搭建annotation开发环境
AspectJ是一个专门用来实现动态代理(AOP编程)的类库AspectJ是面向切面编程的框架
Spring使用就是这个类库实现动态代理的
(三)AOP的annotation实例
三个连接点(切入点) AspectJ的专业术语
1、JoinPoint
切入面
连接点(切入点)
程序执行过程
(五)织入点语法
(六)Advice
1、@Before
2、@ AfterReturning
3、@ AfterThrowing
4、 @After (finally)
5、@ Around
(七)Pointcut
因为Spring要实现AOP(面向切面编程),需要加入切面逻辑的类就会生成动态代理。
在动态代理类中加入切面类从而实现面向切面编程,但生成动态代理存在以下注意事项:
1、被动态代理的类如果实现了某一个接口,那么Spring就会利用JDK类库生成动态代理。
2、如果被动态代理的类没有实现某一个接口,那么Spring就会利用CGLIB类库直接修改二进制码来
生成动态代理(因为利用JDK生成动态代理的类必须实现一个接口),需要在项目中引用CGLIB类库。