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

包头 网站建设网站制作软件区别

包头 网站建设,网站制作软件区别,安徽六安网,极致优化WordPress网站速度✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。 🍎个人主页:Java Fans的博客 🍊个人信条:不迁怒,不贰过。小知识,大智慧。 💞当前专栏…

在这里插入图片描述

✅作者简介:2022年博客新星 第八。热爱国学的Java后端开发者,修心和技术同步精进。
🍎个人主页:Java Fans的博客
🍊个人信条:不迁怒,不贰过。小知识,大智慧。
💞当前专栏:SSM 框架从入门到精通
✨特色专栏:国学周更-心性养成之路
🥭本文内容:一文吃透 Spring 中的 AOP 编程

文章目录

    • AOP 概述
    • AOP 实现分类
    • AOP 术语
    • 基于 Aspectj 实现 AOP 操作
      • 第一版:基于xml(aop:config)配置文件
      • 第二版:基于xml(aop:aspect)配置文件
      • 第三版:基于注解实现通知

在这里插入图片描述

AOP 概述

AOPAspect Oriented Programming 的缩写,是面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOPOOP 的延续,是软件开发中的一个热点,也是 Spring 框架中的一个重要内容,是函数式编程的一种衍生范型

AOP 可以分离业务代码和关注点代码(重复代码),在执行业务代码时,动态的注入关注点代码。切面就是关注点代码形成的类。Spring AOP 中的动态代理主要有两种方式,JDK 动态代理和 CGLIB 动态代理。JDK 动态代理通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口

在这里插入图片描述

AOP 实现分类

AOP 要达到的效果是,保证开发者不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,按照 AOP 框架修改源代码的时机,可以将其分为两类:

  • 静态 AOP 实现, AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。
  • 动态 AOP 实现, AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如 SpringAOP

AOP 术语

  • 连接点(JointPoint)与切入点匹配的执行点,在程序整个执行流程中,可以织入切面的位置,方法的执行前后,异常抛出的位置

  • 切点(PointCut)在程序执行流程中,真正织入切面的方法。

  • 切面(ASPECT)切点+通知就是切面

  • 通知(Advice)切面必须要完成的工作,也叫增强。即,它是类中的一个方法,方法中编写织入的代码。
    前置通知 后置通知
    环绕通知 异常通知
    最终通知

  • 目标对象(Target)被织入通知的对象

  • 代理对象(Proxy)目标对象被织入通知之后创建的新对象

通知的类型

Spring 方面可以使用下面提到的五种通知工作:

通知描述
前置通知在一个方法执行之前,执行通知。
最终通知在一个方法执行之后,不考虑其结果,执行通知。
后置通知在一个方法执行之后,只有在方法成功完成时,才能执行通知。
异常通知在一个方法执行之后,只有在方法退出抛出异常时,才能执行通知。
环绕通知在一个方法调用之前和之后,执行通知。

基于 Aspectj 实现 AOP 操作

基于 Aspectj 实现 AOP 操作,经历了下面三个版本的变化,注解版是我们最常用的。

切入点表达式

作用:声明对哪个类中的哪个方法进行增强

语法:

execution([访问权限修饰符] 返回值 [ 类的全路径名 ] 方法名 (参数列表)[异常])

  • 访问权限修饰符:

    可选项,不写就是四个权限都包含

    写public就表示只包括公开的方法

  • 返回值类型

    必填项 * 标识返回值任意

  • 全限定类名

    可选项,两个点 … 表示当前包以及子包下的所有类,省略表示所有类

  • 方法名

    必填项 * 表示所有的方法 set*表示所有的set方法

  • 形参列表

    必填项

    ()表示没有参数的方法

    (…)参数类型和参数个数随意的方法

    (*)只有一个参数的方法

    (*,String) 第一个参数类型随意,第二个参数String类型

  • 异常信息

    可选项 省略时标识任何异常信息

在这里插入图片描述

第一版:基于xml(aop:config)配置文件

使用 Spring AOP 接口方式实现 AOP, 可以通过自定义通知来供 Spring AOP 识别对应实现的接口是:

  1. 前置通知:MethodBeforeAdvice
  2. 返回通知:AfterReturningAdvice
  3. 异常通知:ThrowsAdvice
  4. 环绕通知:MethodInterceptor

实现步骤:

1、定义业务接口

/*** 使用接口方式实现AOP, 默认通过JDK的动态代理来实现. 非接口方式, 使用的是cglib实现动态代理*/package cn.kgc.spring05.entity;public interface Teacher {String teachOnLine(String course);String teachOffLine(Integer course);
}

2、定义实现类

package cn.kgc.spring05.entity;public class TeacherA implements Teacher{@Overridepublic String teachOnLine(String course) {System.out.println("TeacherA开始"+course+"课程线上教学");if(course.equals("java")){throw new RuntimeException("入门到放弃!");}return course+"课程线上教学";}@Overridepublic String teachOffLine(Integer course) {System.out.println("TeacherA开始"+course+"课程线下教学");return course+"课程线下教学";}
}

3、实现接口定义通知类

前置通知类

package cn.kgc.spring05.advice;import org.springframework.aop.MethodBeforeAdvice;import java.lang.reflect.Method;//前置通知
public class MyMethodBeforeAdvice implements MethodBeforeAdvice {@Overridepublic void before(Method method, Object[] objects, Object o) throws Throwable {System.out.println("------------spring aop 前置通知------------");}
}

后置通知类

package cn.kgc.spring05.advice;import org.springframework.aop.AfterReturningAdvice;import java.lang.reflect.Method;public class MyAfterReturnAdvice implements AfterReturningAdvice {@Overridepublic void afterReturning(Object o, Method method, Object[] objects, Object o1) throws Throwable {System.out.println("------------spring aop 后置通知------------");}
}

4、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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--托管通知--><bean id="after" class="cn.kgc.spring05.advice.MyAfterReturnAdvice"></bean><bean id="before" class="cn.kgc.spring05.advice.MyMethodBeforeAdvice"></bean><bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean><!--AOP的配置--><aop:config><!--切点表达式--><aop:pointcut id="pt" expression="execution(* *(..))"/><aop:advisor advice-ref="before" pointcut-ref="pt"></aop:advisor><aop:advisor advice-ref="after" pointcut-ref="pt"></aop:advisor></aop:config>
</beans>

5、测试

package cn.kgc.spring05;import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;/*** Unit test for simple App.*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config.xml")
public class AppTest
{@AutowiredTeacher teacher;@Testpublic void teachOnLine() {System.out.println(teacher.getClass());String s = teacher.teachOnLine("java");System.out.println("s = " + s);}
}

6、运行结果

在这里插入图片描述

第二版:基于xml(aop:aspect)配置文件

基于 xml(aop:config) 配置文件的方式,增加几个通知,就会创建几个通知类,那我们能否将这些通知类写在一个类中呢?下面就让我来带你们找到解决之法!

配置 AspectJ 标签解读表

在这里插入图片描述

实现步骤:

1、定义业务接口

/*** 使用接口方式实现AOP, 默认通过JDK的动态代理来实现. 非接口方式, 使用的是cglib实现动态代理*/package cn.kgc.spring05.entity;public interface Teacher {String teachOnLine(String course);String teachOffLine(Integer course);
}

2、定义实现类

package cn.kgc.spring05.entity;public class TeacherA implements Teacher{@Overridepublic String teachOnLine(String course) {System.out.println("TeacherA开始"+course+"课程线上教学");if(course.equals("java")){throw new RuntimeException("入门到放弃!");}return course+"课程线上教学";}@Overridepublic String teachOffLine(Integer course) {System.out.println("TeacherA开始"+course+"课程线下教学");return course+"课程线下教学";}
}

3、实现接口定义通知类

package cn.kgc.spring05.advice;public class AllAdvice {public void before(){System.out.println("------------前置通知--------------");}public void afterReturning(){System.out.println("------------后置通知--------------");}public void afterThrowing(){System.out.println("------------异常通知--------------");}public void after(){System.out.println("------------最终通知--------------");}public void around(){System.out.println("------------环绕通知--------------");}
}

4、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:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--托管通知--><bean id="all" class="cn.kgc.spring05.advice.AllAdvice"></bean><bean id="teacherA" class="cn.kgc.spring05.entity.TeacherA"></bean><!--AOP的配置--><aop:config><!--切点表达式--><aop:pointcut id="pt" expression="execution(* *(String))"/><aop:aspect ref="all"><aop:before method="before" pointcut-ref="pt"></aop:before><aop:after-returning method="afterReturning" pointcut-ref="pt"></aop:after-returning><aop:after-throwing method="afterThrowing" pointcut-ref="pt"></aop:after-throwing><aop:after method="after" pointcut-ref="pt"></aop:after>
<!--            <aop:around method="around" pointcut-ref="pt"></aop:around>--></aop:aspect></aop:config>
</beans>

5、测试

package cn.kgc.spring05.advice;import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config2.xml")
public class AllAdviceTest{@AutowiredTeacher teacher;@Testpublic void test01() {System.out.println(teacher.getClass());String s = teacher.teachOnLine("java");System.out.println("s = " + s);}
}

6、运行结果

在这里插入图片描述

第三版:基于注解实现通知

  • 常用 “通知” 注解如下:

    @Aspect 注解将此类定义为切面。
    @Before 注解用于将目标方法配置为前置增强(前置通知)。
    @AfterReturning 注解用于将目标方法配置为后置增强(后置通知)。
    @Around 定义环绕增强(环绕通知)
    @AfterThrowing 配置异常通知
    @After 也是后置通知,与 @AfterReturning 很相似,区别在于 @AfterReturning 在方法执行完毕后进行返回,可以有返回值。@After 没有返回值。

实现步骤:

1、定义业务接口

/*** 使用接口方式实现AOP, 默认通过JDK的动态代理来实现. 非接口方式, 使用的是cglib实现动态代理*/package cn.kgc.spring05.entity;public interface Teacher {String teachOnLine(String course);String teachOffLine(Integer course);
}

2、定义注解

package cn.kgc.spring05.advice;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnoAdvice {
}

3、定义实现类

package cn.kgc.spring05.entity;import cn.kgc.spring05.advice.AnnoAdvice;
import org.springframework.stereotype.Component;@Component
public class TeacherA implements Teacher{@Override@AnnoAdvicepublic String teachOnLine(String course) {System.out.println("TeacherA开始"+course+"课程线上教学");if(course.equals("java")){throw new RuntimeException("入门到放弃!");}return course+"课程线上教学";}@Override@AnnoAdvicepublic String teachOffLine(Integer course) {System.out.println("TeacherA开始"+course+"课程线下教学");return course+"课程线下教学";}
}

4、实现接口定义切面类

首先在类上面添加 @Aspect 注解,将该类转化为切面类,再在类中的各个方法上面使用各自的 “通知” 注解即可实现。

package cn.kgc.spring05.advice;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class AllAdvice {@Pointcut("@annotation(AnnoAdvice)")public void point(){}@Before("point()")public void before(){System.out.println("------------前置通知--------------");}@AfterReturning("point()")public void afterReturning(){System.out.println("------------后置通知--------------");}@AfterThrowing("point()")public void afterThrowing(){System.out.println("------------异常通知--------------");}@After("point()")public void after(){System.out.println("------------最终通知--------------");}@Around("point()")public Object aroundAdvice(ProceedingJoinPoint joinPoint){Object proceed = null;try {System.out.println("----------spring aop 环绕 前通知-----------");proceed = joinPoint.proceed();System.out.println("----------spring aop 环绕 后通知-----------");} catch (Throwable throwable) {throwable.printStackTrace();System.out.println("----------spring aop 环绕 异常通知-----------");}finally {System.out.println("----------spring aop 环绕 最终通知-----------");}return proceed;}
}

5、XML 配置方式

开启包扫描和aspectj自动代理

<?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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--开启包扫描--><context:component-scan base-package="cn.kgc.spring05"></context:component-scan><!--开启aspectj自动代理--><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

6、测试

package cn.kgc.spring05.advice;import cn.kgc.spring05.entity.Teacher;
import junit.framework.TestCase;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring-config3.xml")
public class AllAdviceTest{@AutowiredTeacher teacher;@Testpublic void test01() {System.out.println(teacher.getClass());String s = teacher.teachOnLine("html");System.out.println("s = " + s);}
}

7、运行效果

在这里插入图片描述


  码文不易,本篇文章就介绍到这里,如果想要学习更多Java系列知识点击关注博主,博主带你零基础学习Java知识。与此同时,对于日常生活有困扰的朋友,欢迎阅读我的第四栏目:《国学周更—心性养成之路》,学习技术的同时,我们也注重了心性的养成。

在这里插入图片描述

http://www.yayakq.cn/news/554894/

相关文章:

  • 麦德龙网站建设目标wordpress引导页
  • 做网站 斗地主百度一下浏览器
  • 昆明优秀网站做网站要哪些技术
  • 做网站做什么公司好建筑公司有哪些部门和职位
  • 国内便宜机票网站建设大型网站的技术架构问题
  • 开发一个同城app需要多少钱西安软件优化网站建设
  • phpstorm网站开发网络推广员工作内容
  • 校园二手交易网站开发背景邢台网站制作哪里好
  • 大学网页制作与网站建设大连在哪个网站做网上核名
  • 湛江网站制作计划外贸网站建设的败笔
  • 仿站怎么修改成自己的网站WordPress修改分类id
  • php网站打开一片空白写app程序用什么软件
  • 广西建设厅官方网站电话wordpress linux 重装
  • 新吴区推荐做网站电话广告设计培训班课程
  • 专注大连网站建设不花钱网站怎么做推广
  • 响应式网站建设源码青岛提供网站建设哪家便宜
  • 成都农产品网站建设方案晚上必看的正能量网站
  • 移动端网站开发注意些什么填手机号码的广告
  • 南宁百度 - 网站正在建设中做电影网站被抓
  • asp网站模板源码免费无限下载东莞麻涌网站建设
  • 利用网站新媒体宣传法治建设做好网站如何发布
  • 基于阿里云的电商网站建设wordpress托管建站
  • 商洛网站制作企业不想做网站的原因
  • 报纸做网站宣传费用网络平台加盟代理
  • 新服务器做网站电子上网站建设与维护
  • 200万做网站国内优秀的网站设计
  • 给公司做网站怎么弄wordpress+手机站目录
  • 中国做趋势的网站wordpress 主题根目录
  • wordpress好看博客主题做移动网站优化
  • 网站开发的流程是什么证券投资网站建设