当前位置: 首页 > news >正文

公司网站制作费做无形资产seo技术教程网

公司网站制作费做无形资产,seo技术教程网,优化网站排名如何,绵阳建设局网站文章目录1、什么是AOP1.1、AOP术语1.2、AOP框架2、动态代理2.1、JDK动态代理2.2、CGLIB动态代理3、基于代理类的AOP实现3.1、Spring的通知类型3.2、ProxyFactoryBean4、AspectJ开发4.1、基于XML的声明式AspectJ4.2、基于注解的声明式AspectJ1、什么是AOP 面向切面编程#xf… 文章目录1、什么是AOP1.1、AOP术语1.2、AOP框架2、动态代理2.1、JDK动态代理2.2、CGLIB动态代理3、基于代理类的AOP实现3.1、Spring的通知类型3.2、ProxyFactoryBean4、AspectJ开发4.1、基于XML的声明式AspectJ4.2、基于注解的声明式AspectJ1、什么是AOP 面向切面编程Aspect Oriented Programming提供了另一种角度来思考程序的结构通过这种方式弥补面向对象编程(Object Oriented Programming)的不足。除了类以外AOP提供了切面切面对关注点进行模块化例如横切多个类型和对象的事务管理这些关注点术语通常称作横切(crosscutting)关注点。Spring AOP是Spring的一个重要组件但是Spring IOC并不依赖于Spring AOP这意味着你可以自由选择是否使用AOPAOP提供了强大的中间件解决方案这使得Spring IOC更加完善。我们可以通过AOP来实现日志监听事务管理权限控制等等。 1.1、AOP术语 切面Aspect一个关注点的模块化这个关注点可能会横切多个对象。事务管理是Java应用程序中一个关于横切关注点的很好的例子。在Spring AOP中切面可以使用通过类基于模式XML的风格或者在普通类中以Aspect注解AspectJ风格来实现。连接点Join point程序执行过程中某个特定的点比如某方法调用的时候或者处理异常的时候。在Spring AOP中一个连接点总是代表一个方法的执行。个人理解AOP拦截到的方法就是一个连接点。通过声明一个org.aspectj.lang.JoinPoint类型参数我们可以在通知(Advice)中获得连接点的信息。这个在稍后会给出案例。通知(Advice)在切面Aspect的某个特定连接点上Join point执行的动作。通知的类型包括around“before”after等等。通知的类型将在后面进行讨论。许多AOP框架包括Spring 都是以拦截器作为通知的模型并维护一个以连接点为中心的拦截器链。总之就是AOP对连接点的处理通过通知来执行。个人理解Advice指当一个方法被AOP拦截到的时候要执行的代码。切入点Pointcut匹配连接点Join point的断言。通知Advice跟切入点表达式关联并在与切入点匹配的任何连接点上面运行。切入点表达式如何跟连接点匹配是AOP的核心Spring默认使用AspectJ作为切入点语法。个人理解通过切入点的表达式来确定哪些方法要被AOP拦截之后这些被拦截的方法会执行相对应的Advice代码。引入Introduction声明额外的方法或字段。Spring AOP允许你向任何被通知(Advice)对象引入一个新的接口及其实现类。个人理解AOP允许在运行时动态的向代理对象实现新的接口来完成一些额外的功能并且不影响现有对象的功能。目标对象Target object被一个或多个切面Aspect所通知Advice的对象也称作被通知对象。由于Spring AOP是通过运行时代理实现的所以这个对象永远是被代理对象。个人理解所有的对象在AOP中都会生成一个代理类AOP整个过程都是针对代理类在进行处理。AOP代理AOP proxyAOP框架创建的对象用来实现切面契约aspect contract包括通知方法执行等功能在Spring中AOP可以是JDK动态代理或者是CGLIB代理。织入Weaving把切面aspect连接到其他的应用程序类型或者对象上并创建一个被通知对象。这些可以在编译时例如使用AspectJ编译器类加载时和运行时完成。Spring和其他纯AOP框架一样在运行时完成织入。个人理解把切面跟对象关联并创建该对象的代理对象的过程。 1.2、AOP框架 Spring AOPSpring AOP使用纯Java实现不需要专门的编译过程和类加载器在运行期间通过代理方式向目标类织入增强的代码。AspectJAspectJ是一个基于Java的AOP框架从Spring2.0开始SpringAOP引入了对AspectJ的支持AspectJ扩展了Java语言提供了一个专门的编辑器在编译时提供横向代码的织入。 2、动态代理 Spring中的AOP代理可以是JDK动态代理也可以是CGLIB代理。 2.1、JDK动态代理 JDK动态代理是通过java.lang.reflect.Proxy类来实现的我们可以调用Proxy类的newProxyInstance()方法来创建代理对象。对于使用业务接口的类Spring默认会使用JDK动态代理来实现AOP。 接下来通过一个案例演示Spring中的JDK动态代理 1.创建Java工程导入Spring框架需要的JAR包并发布到类路径下如下图所示 2.创建接口并编写添加和删除方法 package com.nynu.qdy.jdk;public interface UserDao {public void addUser();public void deleteUser(); }3.创建接口实现类实现接口中的方法并在方法中输出一条语句 package com.nynu.qdy.jdk;//目标类 public class UserDaoImpl implements UserDao {public void addUser() {System.out.println(添加用户);}public void deleteUser() {System.out.println(删除用户);} }4.创建切面类MyAspect并在该类中定义模拟权限检查和日志记录的方法。这两个方法表示切面中的通知 package com.nynu.qdy.aspect;//切面类可以存在多个通知Advice(即增强的方法) public class MyAspect {public void check_Permissions() {System.out.println(模拟检查权限.....);}public void log() {System.out.println(模拟记录日志....);} }5.创建代理类该类需要实现InvocationHandller接口并编写代理方法。在代理方法中需要通过Proxy类实现动态代理 package com.nynu.qdy.jdk;import com.nynu.qdy.aspect.MyAspect;import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy;/*** JDK代理类*/ public class JdkProxy implements InvocationHandler {// 声明目标接口private UserDao userDao;// 创建代理方法SuppressWarnings(rawtypes)public Object createProxy(UserDao userDao) {this.userDao userDao;// 1.类加载器ClassLoader classLoader JdkProxy.class.getClassLoader();// 2.被代理对象实现的所有接口Class[] clazz userDao.getClass().getInterfaces();// 3.使用代理类进行增强返回的是代理后的对象return Proxy.newProxyInstance(classLoader, clazz, this);}/*** 所有动态类的方法调用都会交有invoke()方法来处理 * proxy : 被代理后的对象 * method : 将要被执行的方法信息反射* args : 执行方法时需要的参数*/public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 声明切面MyAspect myAspect new MyAspect();// 前增强myAspect.check_Permissions();// 在目标类上调用方法并传入参数Object obj method.invoke(userDao, args);// 后增强myAspect.log();return obj;} }jdkProxy类实现了InvocationHandler接口并实现了接口中的invoke方法 所有动态代理类所调用的方法都会交由该方法处理。在创建的代理方法createProxy()中使用了Proxy类的newProxyInstance()方法来创建代理对象。newProxyInstance()方法中包含3个参数其中第一个参数是当前类的类加载器第2个参数表示的是被代理对象实现的所有接口第3个参数this代表的就是代理类jdkProxy本身。在invoke()方法中目标类方法执行的前后分别执行切面类中的check_Permissions()方法和log()方法。 6.测试类 创建代理对象和目标对象从代理对象中获得对目标对象userDao增强后的对象最后调用该对象中的添加和删除方法 package com.nynu.qdy.jdk;public class jdkTest {public static void main(String[] args) {// 创建代理对象JdkProxy jdkProxy new JdkProxy();// 创建目标对象UserDao userDao new UserDaoImpl();// 从代理对象中获取增强后的目标对象UserDao userDao1 (UserDao) jdkProxy.createProxy(userDao);// 执行方法userDao1.addUser();userDao1.deleteUser();} }7.结果 模拟检查权限..... 添加用户 模拟记录日志.... 模拟检查权限..... 删除用户 模拟记录日志....从结果可以看出userDao实例中的添加用户和删除用户的方法已被成功调用并且在调用前后分别增加了权限检查和记录日志的功能。这种实现了接口的动态代理方式就是Spring中的JDK动态代理。 2.2、CGLIB动态代理 JDK动态代理的使用非常简单但它还有一定的局限性一使 用动态代理的对象必须实现一个或多个接口。如果要对没有实现接只的类进行代理那么可以使用CGLIB代理。 CGLIB ( Code Generation Library )是一个高性能开源的代码生成包它采用非常底层的字 节码技术对指定的目标类生成一个子类 并对子类进行增强。在Spring的核心包中已经集成了CGLIB所需要的包所以开发中不需要另外导入JAR包。 下面通过一个案例来演示CGLIB动态代理的实现过程 1.创建目标类目标类不需要实现任何接口只需定义所需要的方法 package com.nynu.qdy.cglib;//目标类 public class UserDao {public void addUser() {System.out.println(添加用户);}public void deleteUser() {System.out.println(删除用户);}}2.创建代理类该代理类需要实现MethodInterceptor接口并实现接口中的intercept()方法 package com.nynu.qdy.cglib;import java.lang.reflect.Method;import org.springframework.cglib.proxy.Enhancer; import org.springframework.cglib.proxy.MethodInterceptor; import org.springframework.cglib.proxy.MethodProxy;import com.nynu.qdy.aspect.MyAspect;//代理类 public class CglibProxy implements MethodInterceptor {// 代理方法public Object createProxy(Object target) {// 创建一个动态对象Enhancer enhancer new Enhancer();// 确定需要增强的父类设置其父类enhancer.setSuperclass(target.getClass());// 添加回调函数enhancer.setCallback(this);// 返回创建的代理类return enhancer.create();}/*** proxy CGlib根据指定父类生成代理对象 method 拦截的方法 args 拦截的参数数组 methodProxy* 方法的代理对象用于执行父类的方法*/public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {// 创建切面类对象MyAspect myAspect new MyAspect();// 前增强myAspect.check_Permissions();// 目标方法执行Object obj methodProxy.invokeSuper(proxy, args);// 后增强myAspect.log();return obj;}}在该代理方法中首先创建了一个动态类对象Enhancer它是CGLIB的核心类然后调用了Enhancer类的setSuperclass()方法来确定目标对象加下例调用了setCalllback()方法添加回调函数其中的this代表的就是代理类CglibProxy本身最后通过return语句将创建的代理类对象返回。intercept()方法会在程序执行目标方法时被调用方法运行时将会执行切面类中的增强方法。 3.测试 创建测试类CglibTest在该类的main方法中首先创建代理对象和目标对象然后从代理对象中获得增强后的目标对象最后调用对象中的添加和删除方法。 package com.nynu.qdy.cglib;public class CglibTest {public static void main(String[] args) {// 创建代理对象CglibProxy cglibProxy new CglibProxy();// 创建目标对象UserDao userDao new UserDao();// 获取增强后的对象UserDao userDao1 (UserDao) cglibProxy.createProxy(userDao);// 执行方法userDao1.addUser();userDao1.deleteUser();} }4.结果 模拟检查权限..... 添加用户 模拟记录日志.... 模拟检查权限..... 删除用户 模拟记录日志....从结果可以看出目标类UserDao中的方法被成功调用并增强了。这种没有实现接口的代理方式就是CGLIB代理。 3、基于代理类的AOP实现 Spring中的AOP代理默认就是使用JDK动态代理的方式实现的。在Spring中使用ProxyFactoryBean是创建AOP代理的最基本方式。 3.1、Spring的通知类型 Spring中的通知按在目标类方法的连接点位置可以分为以下5种类型 org.allane.intercept.Methodinterceptor (环绕通知) 在目标方法执行前后实施增强可以应用于日志、事务管理等功能。org.springframework.aop.MethodBeforeAdvice (前置通知) 在目标方法执行前实施增强可以应用于权限管理等功能。org.springframework aop .AfterReturningAdvice (后置通知) 在目标方法执行后实施增强可以应用于关闭流、上传文件、删除临时文件等功能。org.springframework.aop.ThrowsAdvice (异常通知) 在方法抛出异常后实施增强可以应用于处理异常记录日志等功能。org.springtramework.aop.IntroductionInterceptor (引介通知) 在目标类中添加一些新的方法和属性可以应用于修改老版本程序(增强类。 3.2、ProxyFactoryBean ProxyFactoryBean是FactoryBean接口的实现类FactoryBean负责实例化一个Bean而ProxyFactoryBean负责为其他Bean创建代理实例。ProxyFactoryBean类中的常用配置属性如下边所示 属性名称描述target代理的目标对象proxyInterfaces代理要实现的接口如果是多个接口可以使用以下格式赋值proxyTargetClass是否对类代理而不是接口设置为true时使用CGLIB代理interceptornames需要织入目标的Advicesingleton返回的代理是否为单实例默认为true即返回单实例optimize当设置为trues时强制使用CGLIB对ProxyFactoryBean类有了初步的了解后接下来通过一个典型的环绕通知案例来演示Spring使用ProxyFactroyBean创建AOP代理 1.创建Java工程导入Spring框架需要的JAR包并发布到类路径下如下图所示 2.创建切面类实现MethodInterceptor接口并实现接口中的invoke()方法来执行目标方法 package com.nynu.qdy.factorybean;import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation;//切面类 public class MyAspect implements MethodInterceptor {public Object invoke(MethodInvocation mi) throws Throwable {check_Permissions();// 执行目标方法Object obj mi.proceed();log();return obj;}public void check_Permissions() {System.out.println(模拟检查权限...);}public void log() {System.out.println(模拟记录日志...);}}为了演示效果在目标方法前后分别执行了检查权限和记录日志的方法这两个方法也就是增强的方法也就是通知 3.创建配置文件并指定代理对象 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.3.xsd!-- 1 目标类 --bean iduserDao classcom.nynu.qdy.jdk.UserDaoImpl /!-- 2 切面类 --bean idmyAspect classcom.nynu.qdy.factorybean.MyAspect /!-- 3 使用Spring代理工厂定义一个名称为userDaoProxy的代理对象 --bean iduserDaoProxyclassorg.springframework.aop.framework.ProxyFactoryBean!-- 3.1 指代理实现的接口 --property nameproxyInterfacesvaluecom.nynu.qdy.jdk.UserDao /!-- 3.2 指定目标对象 --property nametarget refuserDao /!-- 3.3 指定切面植入环绕通知 --property nameinterceptorNames valuemyAspect /!-- 3.4 指定代理方式true使用cglibfalse默认使用jdk动态代理 --property nameproxyTargetClass valuetrue //bean /beans通过 bean 元素定义了目标类和切面然后使用ProxyFactoryBean类定义了代理对象。在定义的代理对象中分别通过 property 子元素指定了代理实现的接口、代理的目标对象、需要织入目标类的通知以及代理方式。 4.创建测试类 package com.nynu.qdy.factorybean;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.nynu.qdy.jdk.UserDao;public class ProxyFactoryBeanTest { //测试类SuppressWarnings(resource)public static void main(String[] args) {/** String xmlPath com/nynu/qdy/factorybean/applicationContext.xml;* * SuppressWarnings(resource) ApplicationContext applicationContext new* ClassPathXmlApplicationContext(xmlPath);*/ApplicationContext applicationContext new ClassPathXmlApplicationContext(applicationContext.xml);// 从spring容器中获得内容UserDao userDao (UserDao) applicationContext.getBean(userDaoProxy);// 执行方法userDao.addUser();userDao.deleteUser();} }5.结果 模拟检查权限... 添加用户 模拟记录日志... 模拟检查权限... 删除用户 模拟记录日志...4、AspectJ开发 AspectJ是一个基于Java语言的AOP框架它提供了强大的AOP功能。 使用AspectJ实现AOP的方式 基于XML的声明式AspectJ基于注解的声明式AspectJ 4.1、基于XML的声明式AspectJ 基于XML的声明式AspectJ是指通过XML文件来定义切面、切入点以及通知所有的切面、切入点和通知都必须定义在 aop:config 元素内。 1. 配置切面 在Spring的配置文件中配置切面使用的是aop:aspect 元素该元素会将一个已定 义好的Spring Bean转换成切面Bean,所以要在配置文件中先定义一个普通的Spring Bean (如上述代码中定义的myAspect)。 定义完成后通过aop:aspect 元素的ref 属性即可引用该Bean。 配置aop:aspect 元素时通常会指定id和ref两个属性如下表所示。 属性名称描述id用于定义该切面的唯一标识名称ref用于引用普通的Spring Bean 2.配置切入点 在Spring的配置文件中切入点是通过aop:pointcut 元素来定义的。当aop:pointcut 元素作为aop:config 元素的子元素定义时表示该切入点是全局切入点它可被多个切面所共享;当aop:pointcut 元素作为aop:aspect 元素的子元素时表示该切入点只对当前切面有效。 在定义aop:pointcut 元素时通常会指定id和expression两个属性如下表所示。 属性名称描述id用于指定切入点的唯一标识名称expression用于指定切入点关联的切入点表达式 在上述配置代码片段中execution(* com.itheima.jdk.. (…))就是定义的切入点表达式该切入点表达式的意思是匹配com.itheima.jdk包中任意类的任意方法的执行。其中execution()是 表达式的主体第1个**表示的是返回类型使用代表所有类型; com.itheima.jdk 表示的是需要拦截的包名后面第2个表示的是类名使用代表所有的类;第3个表示的是方法名使用表示所有方法;后面(…)表示方法的参数其中的“”表示任意参数。需要注意的是**第1个与包名之间有-个空格。** 上面示例中定义的切入点表达式只是开发中常用的配置方式而Spring AOP中切入点表达式的基本格式如下: execution (modi fiers-pattern? ret-type-pattern declaring-type-pattern? name -pattern (param-pattern) throws-pattern?) 上述格式中各部分说明如下。 modifiers- pattern:表示定义的目标方法的访问修饰符如public、 private 等。ret-type- pattern:表示定义的目标方法的返回值类型如void、String 等。delaring-type- pattern: 表示定义的目标方法的类路径如com.itheima.jdk.UserDaolmpl. name- -pattern: 表示具体需要被代理的目标方法如add()方法。param- pattern:表示需要被代理的目标方法包含的参数本章示例中目标方法参数都为空。throws- pattern:表示需要被代理的目标方法抛出的异常类型。 其中带有问号(? ) 的部分如mdifers- patterm、 declaring-type- pattern和throws -pattern表示可配置项;而其他部分属于必须配置项。 3.配置通知 在配置代码中分别使用aop:aspeq 的子元素配置了5种常用通知这5个子元素不支持使用子元素但在使用时可以指定一些属性如下表所示。 属性名称描述pointcut该属性用于指定-一个切入点表达式 Spring 将在匹配该表达式的连接点时织入该通知pointcut-ref该属性指定一个已经存在的切入点名称如配置代码中的myPointCut。通常pointut和pointcut-ref两个属性只需要使用其中之一method该属性指定一个方法名指定将切面Bean中的该方法转换为增强处理throwing该属性只对 after-throwing 元素有效 它用于指定一个形参名异常通知方法可以通过该形参访问目标方法所抛出的异常returning该属性只对 after-returning 元素有效 它用于指定一个形参名异常通知方法可以通过该形参访问目标方法的返回值了解了如何在XML文件中配置切面、切入点和通知后接下来通过一个案例来演示如何在Spring中基于XML的声明式Aspect J 1.创建切面类并在类中分别定义不同类型的通知 package com.nynu.qdy.aspectj.xml;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;public class MyAspect {// 前置通知public void myBefore(JoinPoint joinPoint) {System.out.println(前置通知模拟执行权限检查);System.out.println(目标类是 joinPoint.getTarget());System.out.println(,被植入增强的目标方法为 joinPoint.getSignature().getName());}// 后置通知public void myAfterReturning(JoinPoint joinPoint) {System.out.println(后置通知模拟记录日志);System.out.println(被植入增强处理的目标方法为 joinPoint.getSignature().getName());}/*** 环绕通知 ProceedingJoinPoint 是JoinPoint子接口。表示可以执行目标方法 1.必须是Object类型的返回值 2.* 必须接受一个参数类型为ProceedingJoinPoint 3. 必须throws Throwable* * throws Throwable*/public Object myAround(ProceedingJoinPoint proceedingJoinPoint)throws Throwable {// 开始System.out.println(环绕开始执行目标方法之前模拟开启事物。。。。);// 执行当前目标方法Object obj proceedingJoinPoint.proceed();// 结束System.out.println(环绕结束执行目标方法之后。关闭模拟事物。。。);return obj;}// 异常通知public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {System.out.println(异常通知 出错了 e.getMessage());}// 最终通知public void myAfter() {System.out.println(最终通知模拟方法结束后的释放资源);} }在切面类中分别定义了5种不同类型的通知在通知中使用了JoinPoint 接口及其子接口ProceedingJoinPoint作为参数来获得目标对象的类名、目标方法名和目标方法参数等。 需要注意的是环绕通知必须接收一个类型为ProceedingJoinPoint的参数返回值也必须是Object类型且必须抛出异常。异常通知中可以传入Throwable类型的参数来输出异常信息。 2.创建配置文件并编写相关配置 ?xml version1.0 encodingUTF-8? beans xmlnshttp://www.springframework.org/schema/beansxmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlns:aophttp://www.springframework.org/schema/aopxsi:schemaLocationhttp://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-4.3.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop-4.3.xsd!-- 1 目标类 --bean iduserDao classcom.nynu.qdy.jdk.UserDaoImpl /!-- 2 切面 --bean idmyAspect classcom.nynu.qdy.aspectj.xml.MyAspect /!-- 3 aop编程 --aop:config!-- 切面配置 --aop:aspect refmyAspect!-- 3.1 配置切入点通知最后增强哪些方法 --aop:pointcut expressionexecution(* com.nynu.qdy.jdk.*.*(..))idmyPointCut /!-- 3.2 关联通知Advice和切入点pointCut --!-- 3.2.1 前置通知 --aop:before methodmyBefore pointcut-refmyPointCut /aop:after-returning methodmyAfterReturningpointcut-refmyPointCut returningreturnVal /!-- 3.2.3 环绕通知 --aop:around methodmyAround pointcut-refmyPointCut /aop:after-throwing methodmyAfterThrowingpointcut-refmyPointCut throwinge /aop:after methodmyAfter pointcut-refmyPointCut //aop:aspect/aop:config /beans3.创建测试类并在类中对方法进行增强 package com.nynu.qdy.aspectj.xml;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;import com.nynu.qdy.jdk.UserDao;public class TestXmlAspectj {SuppressWarnings(resource)public static void main(String[] args) {String xmlPath com/nynu/qdy/aspectj/xml/applicationContext.xml;ApplicationContext applicationContext new ClassPathXmlApplicationContext(xmlPath);UserDao userDao (UserDao) applicationContext.getBean(userDao);userDao.addUser();} }4.结果 前置通知模拟执行权限检查 目标类是com.nynu.qdy.jdk.UserDaoImpl184cf7cf ,被植入增强的目标方法为 addUser 环绕开始执行目标方法之前模拟开启事物。。。。 添加用户 最终通知模拟方法结束后的释放资源 环绕结束执行目标方法之后。关闭模拟事物。。。 后置通知模拟记录日志 被植入增强处理的目标方法为 addUser4.2、基于注解的声明式AspectJ 与基于代理类的AOP实现相比基于XML的声明式ApectJ要便捷得多但是它也存在着一些 缺点那就是要在Spring文件中配置大量的代码信息。为了解决这个问题AspectJ 框架为AOP的实现提供了一套注解用以取代Spring配置文件中为实现AOP功能所配置的臃肿代码。 关于AspectJ注解的介绍如下表所示 注解名称描述Aspect用于定义一个切面Pointcut用于定义切入点表达式。在使用时还需定义一个包含名字和任意参数的方法签名来表示切入点 名称。实际上这个方法签名就是一一个返回值为 void,且方法体为空的普通的方法Before用于定义前置通知相当于BeforeAdvice。在使用时通常需要指定一一个value属性值该属性值用于指定一个切入点表达式 (可以是已有的切入点也可以直接定义切入点表达式)AfterReturning用于定义后置通知相当于AfterReturningAdvice。 在使用时可以指定pointcut/value 和 returning属性其中pointcut/value 这两个属性的作用一样都用于指定切入点表达式。returning属性值用于表示Advice方法中可定义与此同名的形参该形参可用于访问目标方法的返回值Around用于定义环绕通知相当于MethodInterceptor.在使用时需要指定一个value属性该属性用于指定该通知被植入的切入点After Throwing用于定义异常通知来处理程序中未处理的异常相当于ThrowAdvice 。在使用时可指定pointcut/value和throwing属性。其中pointcutvalue用于指定切入点表达式而throwing属性值用于指定一个形参名来表示Advice方法中可定义与此同名的形参该形参可用于访问目标方法抛出的异常After用于定义最终final通知不管是否异常该通知都会执行。使用时需要指定一个 value属性该属性用于指定该通知被植入的切入点DeclareParents用于定义引介通知相当于IntroductionInterceptor (不要求掌握)为了使读者可以快速地掌握这些注解接下来重新使用注解的形式来实现上一小节的案例具体步骤如下 1.复制上一节切面类并做相应修改 package com.nynu.qdy.aspectj.annotation;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;Aspect Component public class MyAspect {// 切入点表达式Pointcut(execution(* com.nynu.qdy.jdk.*.*(..)))// 使用一个返回值为void ,方法体为空的方法来命名切入点private void myPointCut() {}// 前置通知Before(myPointCut())public void myBefore(JoinPoint joinPoint) {System.out.println(前置通知模拟执行权限检查);System.out.println(目标类是 joinPoint.getTarget());System.out.println(,被植入增强的目标方法为 joinPoint.getSignature().getName());}// 后置通知AfterReturning(myPointCut())public void myAfterReturning(JoinPoint joinPoint) {System.out.println(后置通知模拟记录日志);System.out.println(被植入增强处理的目标方法为 joinPoint.getSignature().getName());}/*** 环绕通知 ProceedingJoinPoint 是JoinPoint子接口。表示可以执行目标方法 1.必须是Object类型的返回值 2.* 必须接受一个参数类型为ProceedingJoinPoint 3. 必须throws Throwable* * throws Throwable*/Around(myPointCut())public Object myAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {// 开始System.out.println(环绕开始执行目标方法之前模拟开启事物。。。。);// 执行当前目标方法Object obj proceedingJoinPoint.proceed();// 结束System.out.println(环绕结束执行目标方法之后。关闭模拟事物。。。);return obj;}// 异常通知AfterThrowing(value myPointCut(), throwing e)public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {System.out.println(异常通知 出错了 e.getMessage());}// 最终通知After(myPointCut())public void myAfter() {System.out.println(最终通知模拟方法结束后的释放资源);} }在切面类中首先使用Aspect注解定义了切面类由于该类在Spring中是作为组件使用的所以还需要添加Component注解才能生效。然后使用了Poincut注解来配置切入点表达式并通过定义方法来表示切入点名称。接下来在每个通知相应的方法上添加了相应的注解并将切入点名称“myPointCut作为参数传递给需要执行增强的通知方法。如果需要其他参数(如异常通知的异常参数)可以根据代码提示传递相应的属性值。 2.目标类com.itheima.jdk.UserDaolmpl中添加注解Repository(“userDao”) package com.nynu.qdy.jdk;import org.springframework.stereotype.Repository;Repository(userDao) public class UserDaoImpl implements UserDao {public void addUser() {System.out.println(添加用户);}public void deleteUser() {System.out.println(删除用户);}}3.创建配置文件applicationContext.xml ?xml version1.0 encodingUTF-8? beans xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexmlnshttp://www.springframework.org/schema/beansxmlns:contexthttp://www.springframework.org/schema/contextxmlns:aophttp://www.springframework.org/schema/aopxmlns:txhttp://www.springframework.org/schema/txxsi:schemaLocationhttp://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd !-- 指定需要扫描的包使注解生效 --context:component-scanbase-packagecom.nynu.qdy /!-- 启动基于注解的声明式AspectJ支持 --aop:aspectj-autoproxy//beans4.创建测试类 package com.nynu.qdy.aspectj.annotation;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;import com.nynu.qdy.jdk.UserDao;public class TestAnnotation {SuppressWarnings(resource)public static void main(String[] args) {String xmlPath com/nynu/qdy/aspectj/annotation/applicationContext.xml;ApplicationContext applicationContext new ClassPathXmlApplicationContext(xmlPath);// 1 从容器中获得内容UserDao userDao (UserDao) applicationContext.getBean(userDao);// 2 执行方法userDao.addUser();userDao.deleteUser();} }5.结果 环绕开始执行目标方法之前模拟开启事物。。。。 前置通知模拟执行权限检查 目标类是com.nynu.qdy.jdk.UserDaoImpl71809907 ,被植入增强的目标方法为 addUser 添加用户 环绕结束执行目标方法之后。关闭模拟事物。。。 最终通知模拟方法结束后的释放资源 后置通知模拟记录日志 被植入增强处理的目标方法为 addUser 环绕开始执行目标方法之前模拟开启事物。。。。 前置通知模拟执行权限检查 目标类是com.nynu.qdy.jdk.UserDaoImpl71809907 ,被植入增强的目标方法为 deleteUser 删除用户 环绕结束执行目标方法之后。关闭模拟事物。。。 最终通知模拟方法结束后的释放资源 后置通知模拟记录日志 被植入增强处理的目标方法为 deleteUser如果同一个连接点有多个通知需要执行那么在同一切面中目标方法之前的前置通知和环绕通知的执行顺序是未知的目标方法之后的后置通知和环绕通知的执行顺序也是位置的。
http://www.zqtcl.cn/news/754141/

相关文章:

  • 中英语双语网站咋做提供网站建设设计外包
  • 云网站功能江门网站seo关键词排名优化
  • 潍坊网站建设外贸制作html网站
  • 网站友情链接怎么添加定制酒营销方案
  • 目前最流行网站开发软件泰州市建设工程招标网
  • 福州网站优化me域名网站
  • 网站 案例互联网外包公司值得去吗
  • 做医疗护具网站浙江立鹏建设有限公司网站
  • 织梦制作手机网站c 网站开发需要学什么软件
  • 罗湖网站制作阿里巴巴开店网站怎么做
  • 深圳住房和建设局网站 招标怎样建设自己的视频网站
  • 网站建设的目的模板茶网站建设需要多少钱
  • 珠海市城乡住房建设局网站网站外链
  • 福田做网站需要多少钱做淘宝客网站性质
  • html网站怎么进入后台网站主题怎么写
  • wordpress怎么ftp建站高端网站建设域名注册
  • 我用织梦5.7做个网站应该把淘宝客店铺链接放到哪聊天软件开发需要多少钱
  • 站长工具爱站竞价单页网站制作
  • 网站分类目录大全购物网站大全棉鞋
  • 网站镜像做排名建立外贸英文网站应该怎么做
  • 上海做网站就用乐云seo手机网站cms 下载
  • 做网站需要固定ip么灵犀科技网站建设
  • 深圳高端做网站建设网站备案与不备案区别
  • 家居企业网站建设公司苏州高新区建设局网站管网
  • 体育门户网站模板seo网络推广有哪些
  • 石家庄网站建设教程百度云下载
  • 怎样查看网站建设时间公司网站关键词优化
  • 网站淘宝推广怎么做网站seo基本流程
  • miit网站备案济南哪里做网站
  • 做网站软件的公司前端优化