做设计任务的网站,c 做的网站怎么上传图片,外贸网站建设评价,安阳市有几个区几个县问题#xff1a;什么是AOP#xff1f;
答#xff1a;AOP基本概念#xff1a;Aspect-Oriented Programming#xff0c;面向方面编程的简称#xff0c;Aspect是一种新的模块化机制#xff0c;用来描述分散在对象、类或方法中的横切关注点(crosscutting concern)#xff…问题什么是AOP
答AOP基本概念Aspect-Oriented Programming面向方面编程的简称Aspect是一种新的模块化机制用来描述分散在对象、类或方法中的横切关注点(crosscutting concern) 从关注点中分离出横切关注点是面向方面程序设计的核心所在。分离关注点使得解决特定领域问题的代码从业务逻辑中独立出来业务逻辑的代码中不再含有针对特 定领域问题代码的调用业务逻辑同特定领域问题的关系通过方面来封装、维护这样原本分散在整个应用程序中的变动就可以很好地管理起来。
个人理解所谓的AOP就是把我们的程序的执行看成是一个方块的面包然后切成了一片一片的吐司--这些吐司就是我们一个一个的方法。然后在这些吐司片的前面后面、甚至是里面来做一些特定条件下发生的特定事情比如嵌入几个葡萄干、给前面加苹果酱、给后面加草莓酱这样的事情。。优势在于你可以在自己的AOP方法中规定一个加苹果酱的理由满足这个理由的话就可以加苹果酱而不用在每个方法中都特定的指出加苹果酱加草莓酱什么的··个人理解···。 AOP的实现有很多的方式我这边使用Spring中自带的aop来做一些业务逻辑的实现。
在Spring中实现aop的方式有两种分别是通过xml配置和通过注解配置。下面来介绍这两种方式。
在介绍他们之前先看一下项目的结构 上图中ServiceAspect是我们使用注解的方式来实现AOP的类InteceptorXML是使用XML来实现AOP的类TestAop是测试方法TestServiceImplTestService是用来被AOP的动作需要明确的是AOP的动作建议都发生在service层面。application-context.xml是我的配置文件。
1.通过注解配置。
我注解AOP的代码如下 package test.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;import test.entity.User;Component
// 声明这是一个组件
Aspect
// 声明这是一个切面bean
public class ServiceAspect {// 配置切入点该方法无方法体主要是为了同类中其他方法使用此处配置的切入点 ----见(1)Pointcut(execution(* test.service..*.*(..)))public void aspect() {}// 配置前置通知使用在方法aspect()上注册的切入点同时接受JoinPoint切入点对象可以没有该参数 ----见(2)Before(aspect()args(id))public void before(JoinPoint joinPoint, long id) {System.out.println(id ------------------);System.out.println(before-- joinPoint);}// 配置后置通知使用在方法aspect()上注册的切入点----见(3)After(aspect()args(id))public void after(JoinPoint joinPoint, long id) {System.out.println(id after----------------------);System.out.println(after-- joinPoint);}// 配置环绕通知----见(4)Around(aspect())public Object around(JoinPoint joinPoint) {long start System.currentTimeMillis();try {Object o((ProceedingJoinPoint) joinPoint).proceed();User user (User)o;System.out.println(-----arounduser.toString());long end System.currentTimeMillis();System.out.println(around -- joinPoint \tUse time : (end - start) ms!);return user;} catch (Throwable e) {long end System.currentTimeMillis();System.out.println(around __ joinPoint \tUse time : (end - start) ms with exception : e.getMessage());return null;}}// 配置后置返回通知,使用在方法aspect()上注册的切入点----见(5)AfterReturning(pointcut aspect(), returning returnVal)public void afterReturning(JoinPoint joinPoint, Object returnVal) {System.out.println(afterReturning executed, return result is returnVal);}// 配置抛出异常后通知,使用在方法aspect()上注册的切入点----见(6)AfterThrowing(pointcut aspect(), throwing ex)public void afterThrow(JoinPoint joinPoint, Exception ex) {System.out.println(afterThrow-- joinPoint \t ex.getMessage());}
}很多内容在注释中已经有了这里说一下几个关键的容易让人不明白的地方
1Pointcut(execution(* test.service..*.*(..)))就是我们定义的切入点在括号里面的参数是指定了哪些方法是在考虑切入的范围内的
* test.service..*.*(..)可以这样来解剖
第一个* 表示被拦截的方法可以是任意的返回类型
test.service:指定了要拦截的包
..这两个..表示的是被指定的拦截包test.service中所有的子包中的类的方法都要考虑到拦截的范围中
*:表示任意的类
.*:表示任意的方法
(..):表示任意的方法参数
总结起来就是告诉我们这样一个信息要拦截test.service中所有子包中的所有类的所有方法这些方法的返回值可以是任意的参数可以是任意的。
当然我们也可以特定许多内容但是格式不要变例如
Pointcut(“execution(* test.service..*.add*(..))”)
那么所要拦截的方法就必须以add来开头了。
切入点的方法中不实现任何的操作作用只是提供给其他的切面来使用。 2
Before(aspect()args(id))中的 aspect()指定指定切入点的方法就是我们定义为pointCut的aspect()方法然后args(id)我们获取了所拦截的方法的传入的参数中的id在before方法中我们可以在切入点执行以前来做一些操作。 其中的joinPoint是切入点的相关信息。 3
After(aspect()args(id))同2只是这是在切入点执行完成以后来做出一些处理。 4
Around(aspect())是环绕通知在环绕通知中我们能切入点的很多内容进行修改
其中通过Object o((ProceedingJoinPoint) joinPoint).proceed();我们就可以让切入点的方法完成获得他的运行结果
然后User user (User)o;我们把它转换为User对象如果在return user之前我们加上user.setName(after aa);就可以改变切入点的运行结果。
这种操作对于很多的错误检测以及格式检测是很有用处的。 5
AfterReturning(pointcut aspect(), returning returnVal)
这里是切入点有返回结果后做的操作通过returning的定义我们能获得切入点的返回结果 6
AfterThrowing(pointcut aspect(), throwing ex)
这里可以在切入点抛出异常后做一些工作通过定义throwing我们能获得抛出的异常对象。 相关代码
application-context.xml ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:phttp://www.springframework.org/schema/pxmlns:contexthttp://www.springframework.org/schema/contextxmlns:utilhttp://www.springframework.org/schema/util xmlns:jeehttp://www.springframework.org/schema/jeexmlns:txhttp://www.springframework.org/schema/tx xmlns:mvchttp://www.springframework.org/schema/mvcxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
context:component-scan base-packagetest !--开启spring自定义的包扫描我定义的为扫描test包下所有内容--
context:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/!--这里不扫描controller在mvc中扫描安全又可靠--
/context:component-scan
aop:aspectj-autoproxy proxy-target-classtrue/aop:aspectj-autoproxy!--开启注释方式的spring aop--
bean iduserService classtest.service.impl.UserService/bean!--注入userService--
/beansUserServicepackage test.service.impl;import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;import test.entity.User;public class UserService {private final static Log log LogFactory.getLog(UserService.class);public User get(long id) {if (log.isInfoEnabled()) {log.info(getUser method . . .);}User user new User(1, test);return user;}public void save(User user) {if (log.isInfoEnabled()) {log.info(saveUser method . . .);}}public boolean delete(long id) throws Exception {if (log.isInfoEnabled()) {log.info(delete method . . .);throw new Exception(spring aop ThrowAdvice演示);}return false;}
}test方法 package demo;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import test.entity.User;
import test.service.impl.UserService;public class TestAop {public static void main(String[] args) {ApplicationContext aContext new ClassPathXmlApplicationContext(application-context.xml);//加载spring文件UserService userService (UserService) aContext.getBean(userService);//获得userserviceUser user userService.get(1L);//调用get方法System.out.println(user);try {userService.delete(1L);//调用delete方法} catch (Exception e) {System.out.println(Delete user : e.getMessage());}}
}测试结果 2.通过XML来配置
通过xml来配置AOP操作都在xml文件中完成
在xml中做如下配置 ?xml version1.0 encodingUTF-8?
beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:phttp://www.springframework.org/schema/pxmlns:contexthttp://www.springframework.org/schema/contextxmlns:utilhttp://www.springframework.org/schema/util xmlns:jeehttp://www.springframework.org/schema/jeexmlns:txhttp://www.springframework.org/schema/tx xmlns:mvchttp://www.springframework.org/schema/mvcxmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/utilhttp://www.springframework.org/schema/util/spring-util-3.0.xsdhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsdhttp://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsdhttp://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsdhttp://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsdhttp://www.springframework.org/schema/mvchttp://www.springframework.org/schema/mvc/spring-mvc-3.0.xsdhttp://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
!-- context:component-scan base-packagetest
context:exclude-filter typeannotation expressionorg.springframework.stereotype.Controller/
/context:component-scan
aop:aspectj-autoproxy proxy-target-classtrue/aop:aspectj-autoproxy --
bean iduserService classtest.service.impl.UserService/beanbean idinteceptorXML classtest.aop.InteceptorXML/bean
aop:config
aop:aspect idaspectd refinteceptorXML
aop:pointcut expressionexecution(* test.service..*.*(..)) idmypointCutMethod/
aop:before methoddoAccessCheck pointcut-refmypointCutMethod /
/aop:aspect
/aop:config
/beans在xml中我们指定了用来作为拦截器的bean----inteceptorXML类似的指定了切入点
aop:aspect idaspectd refinteceptorXML指定了拦截器为interceptorXML。 execution(* test.service..*.*(..))并指定了id为mypointCutMethod然后定义了 aop:before methoddoAccessCheck pointcut-refmypointCutMethod / 指定了调用doAccessCheck来做before拦截其他拦截我没有指定这里都可以指定的。 inteceptorXml package test.aop;import org.aspectj.lang.ProceedingJoinPoint;public class InteceptorXML {public void doAccessCheck() {System.out.println(before advice);}public void doWriteLog() {System.out.println(after advice);}public void doWriteErrorLog() {System.out.println(Exception advice);}public Object doAroundMethod(ProceedingJoinPoint pjp) throws Throwable {System.out.println(enter around advice method.);Object obj pjp.proceed();System.out.println(exit around advice method.);return obj;}
}运行上面的测试方法得到的结果如下