Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

37 篇文章 22 订阅
订阅专栏

1. Spring AOP 是什么

学习 Spring AOP 之前,先要了解 AOP 是什么

AOP(Aspect Oriented Programming):面向切面编程,它和 OOP(面向对象编程)类似。

它是一种思想,是对某一类事情的集中处理。

比如用户登录权限的效验,在学习 AOP 之前,在需要判断用户登录的页面,都要各自实现或调用用户验证的方法,学习 AOP 之后,我们只需要在某一处配置一下,那么所有需要判断用户登录的页面就全部可以实现用户登录验证了,不用在每个方法中都写用户登录验证了

AOP 是一种思想,而 Spring AOP 是实现(框架),这种关系和 IOC(思想)与 DI(实现)类似


2. 为什么要用 AOP

  1. 高频:对于这种功能统一,且使用地方较多的功能,可以考虑用 AOP 来处理(比如 用户登录验证)
  2. 使⽤ AOP 可以扩充多个对象的某个能⼒,AOP 可以说是 OOP 的补充和完善(比如 现在要实现的业务和这个通用的功能没什么关系,但处于安全考虑,又必须进行登录的验证)

除了统一的用户登录判断外,AOP 还可以实现

  • 统一日志处理
  • 统一方法执行时间统计
  • 统一的返回格式设置
  • 统一的异常处理
  • 事务的开启和提交等

3. 怎么学 Spring AOP

Spring AOP 学习主要分为3个部分

  1. 学习 AOP 是如何组成的
  2. 学习 Spring AOP 使用
  3. 学习 Spring AOP 实现原理

4. AOP 组成

(1)切面(Aspect)

定义 AOP 是针对某个统一的功能的,这个功能就叫做一个切面,比如用户登录功能或方法的统计日志,他们就各是一个切面。切面是由切点和通知组成的

(2)连接点(Join Point)

所有可能触发 AOP(拦截方法的点)就称为连接点

(3)切点(Pointcut)

切点的作用就是提供一组规则来匹配连接点,给满足规则的连接点添加通知,总的来说就是,定义 AOP 拦截的规则的

切点相当于保存了众多连接点的一个集合(如果把切点看成一个表,而连接点就是表中一条一条的数据)

(4)通知(Advice)

切面的工作就是通知

通知:规定了 AOP 执行的时机和执行的方法

Spring 切面类中,可以在方法上使用以下注解,会设置方法为通知方法,在满足条件后悔通知本方法进行调用

  1. 前置通知 @Before:通知方法会在目标方法调用之前执行
  2. 后置通知 @After:通知方法会在目标方法返回或者抛出异常后调用
  3. 返回之后通知 @AfterReturning:通知方法会在目标方法返回后调用
  4. 抛异常后通知:@AfterThrowing:通知方法会在目标方法爬出异常之后调用
  5. 环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

举个例子,在一个生产型公司中

通知相当于底层的执行者,切点是小领导制定规则,切面是大领导制定公司的发展方向,连接点是属于一个普通的消费者用户

以多个⻚⾯都要访问⽤户登录权限为例子,AOP 整个组成部分如图所示

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zkAm0DT8-1676207159825)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676183469495.png)]


5. Spring AOP 实现

Spring AOP 实现步骤

  1. 添加 Spring AOP 框架支持
  2. 定义切面和切点
  3. 实现通知

接下来我们使⽤ Spring AOP 来实现⼀下 AOP 的功能,完成的⽬标是拦截所有 UserController ⾥⾯的

⽅法,每次调⽤ UserController 中任意⼀个⽅法时,都执⾏相应的通知事件。

5.1 添加 Spring AOP 框架支持

在中央仓库中搜锁 Spring AOP Maven Repository: Search/Browse/Explore (mvnrepository.com)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uIsDmKWi-1676207159826)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676185167353.png)]

在 pom.xml 中添加如下配置:

<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-aop -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

5.2 定义切面和切点

@Aspect // 当前类是一个切面
@Component
public class UserAspect {
    // 定义一个切点(设置拦截规则)
    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
    public void pointcut() {
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-p4mQspnI-1676207159827)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676186116916.png)]

5.3 实现通知方法

  1. 前置通知 @Before:通知方法会在目标方法调用之前执行
  2. 后置通知 @After:通知方法会在目标方法返回或者抛出异常后调用
  3. 返回之后通知 @AfterReturning:通知方法会在目标方法返回后调用
  4. 抛异常后通知:@AfterThrowing:通知方法会在目标方法爬出异常之后调用
  5. 环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

实现通知方法也就是在什么时机执行什么方法

@Aspect // 当前类是一个切面
@Component
public class UserAspect {
    // 定义一个切点(设置拦截规则)
    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")
    public void pointcut() {
    }

    // 定义 pointcut 切点的前置通知
    @Before("pointcut()")
    public void doBefore() {
        System.out.println("执行前置通知");
    }

    // 后置通知
    @After("pointcut()")
    public void doAfter() {
        System.out.println("执行后置通知");
    }

    // 返回之后通知
    @AfterReturning("pointcut()")
    public void doAfterReturning() {
        System.out.println("执行返回之后通知");
    }

    // 抛出异常之后通知
    @AfterThrowing("pointcut()")
    public void doAfterThrowing() {
        System.out.println("执行抛出异常之后通知");
    }
}
@RestController
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/sayhi")
    public String sayHi() {
        System.out.println("sayhi 方法被执行");
        int num = 10/0;
        return "你好,java";
    }

    @RequestMapping("/sayhi2")
    public String sayHi2() {
        System.out.println("sayhi2 方法被执行");
        return "你好,java2";
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qVSOeHQj-1676207159828)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676189891534.png)]

环绕通知:@Around:通知包裹了被通知的方法,在被通知的方法通知之前和调用之后执行自定义的行为

// 添加环绕通知
@Around("pointcut()")
public Object doAround(ProceedingJoinPoint joinPoint) {
    Object result = null;
    System.out.println("环绕通知:前置方法");
    try {
        // 执行拦截方法
        result = joinPoint.proceed();
    } catch (Throwable e) {
        e.printStackTrace();
    }
    System.out.println("环绕通知:后置方法");
    return result;
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5xizlv7M-1676207159828)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676190278115.png)]

5.4 使⽤ AOP 统计 UserController 每个⽅法的执⾏时间 StopWatch

Spring AOP 中统计时间用 StopWatch 对象

    // 添加环绕通知
    @Around("pointcut()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        // spring 中的时间统计对象
        StopWatch stopWatch = new StopWatch();
        Object result = null;
        try {
            stopWatch.start(); // 统计方法的执行时间,开始计时
            // 执行目标方法,以及目标方法所对应的相应通知
            result = joinPoint.proceed();
            stopWatch.stop(); // 统计方法的执行时间,停止计时
        } catch (Throwable e) {
            e.printStackTrace();
        }
        System.out.println(joinPoint.getSignature().getDeclaringTypeName() + "." +
                joinPoint.getSignature().getName() +
                "执行花费的时间:" + stopWatch.getTotalTimeMillis() + "ms");
        return result;
    }

5.4 切点表达式说明 AspectJ

AspectJ 表达式语法:SpringAOP & AspectJ

    @Pointcut("execution(* com.example.springaop.controller.UserController.*(..))")

AspectJ 语法(Spring AOP 切点的匹配语法):

切点表达式由切点函数组成,其中 execution() 是最常⽤的切点函数,⽤来匹配⽅法,语法为:

execution(<修饰符><返回类型><包.类.⽅法(参数)><异常>)

AspectJ ⽀持三种通配符

* :匹配任意字符,只匹配⼀个元素(包,类,或⽅法,⽅法参数)

… :匹配任意字符,可以匹配多个元素 ,在表示类时,必须和 * 联合使⽤。

+ :表示按照类型匹配指定类的所有类,必须跟在类名后⾯,如 com.cad.Car+ ,表示继承该类的所有⼦类包括本身

修饰符,一般省略

  • public 公共方法
  • *任意

返回值,不能省略

  • void 返回没有值
  • String 返回值字符串
  • *任意

包,通常不省略,但可以省略

  • com.gyf.crm 固定包
  • com.gyf.crm.*.service crm 包下面子包任意(例如:com.gyf.crm.staff.service)
  • com.gyf.crm… crm 包下面的所有子包(含自己)
  • com.gyf.crm.*service… crm 包下面任意子包,固定目录 service,service 目录任意包

类,通常不省略,但可以省略

UserServiceImpl 指定类

*Impl 以 Impl 结尾

User* 以 User 开头

*任意

方法名,不能省略

addUser 固定方法

add* 以 add 开头

*DO 以 DO 结尾

*任意

参数

() 无参

(int) 一个整形

(int,int)两个整型

(…) 参数任意

throws可省略,一般不写

表达式示例

  • execution(* com.cad.demo.User.*(…)) :匹配 User 类⾥的所有⽅法
  • execution(* com.cad.demo.User+.*(…)) :匹配该类的⼦类包括该类的所有⽅法
  • execution(* com.cad..(…)) :匹配 com.cad 包下的所有类的所有⽅法
  • execution(* com.cad….(…)) :匹配 com.cad 包下、⼦孙包下所有类的所有⽅法
  • execution(* addUser(String, int)) :匹配 addUser ⽅法,且第⼀个参数类型是 String,第⼆个参数类型是 int

6. Spring AOP 实现原理

Spring AOP 是构建在动态代理基础上,因此 Spring 对 AOP 的支持局限于方法级别的拦截

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pDirrfMk-1676207159829)(C:\Users\28463\AppData\Roaming\Typora\typora-user-images\1676192122209.png)]

Spring AOP 动态代理实现:

默认情况下,实现了接⼝的类,使⽤ AOP 会基于 JDK ⽣成代理类,没有实现接⼝的类,会基于 CGLIB ⽣成代理类

  1. JDK Proxy(JDK 动态代理)

  2. CGLIB Proxy:默认情况下 Spring AOP 都会采用 CGLIB 来实现动态代理,因为效率高

    CGLIB 实现原理:通过继承代理对象来实现动态代理的(子类拥有父类的所有功能)

    CGLIB 缺点:不能代理最终类(也就是被 final 修饰的类)

6.1 生成代理的时机 :织入(Weaving)

织入是把切面应用到目标对象并创建新的代理对象的过程,切面在指定的连接点被织入到目标对象中

在目标对象的生命周期中有多个点可以进行织入

  1. 编译期:切面在目标类编译时被织入,这种方法需要特殊的编译器,AspectJ 的织入编译器就是以这种方式织入切面的
  2. 类加载期:切面在目标类加载到 JVM 时被织入,这种方式需要特殊的类加载器,它可以在目标类被引入应用之前增强该目标类的字节码,AspectJ5 的加载时织入 (load-time weaving. LTW)就支持以这种方式织入切面
  3. 运行期:切面在应用运行的某一时刻被织入,一般情况下,在织入切面时,AOP容器会为目标对象动态创建一个代理对象,Spring AOP 就是以这种方式织入切面的

6.2 JDK 动态代理实现

JDK 动态代理就是依靠反射来实现的

//动态代理:使⽤JDK提供的api(InvocationHandler、Proxy实现),此种⽅式实现,要求被
代理类必须实现接⼝
public class PayServiceJDKInvocationHandler implements InvocationHandler {
 
 	//⽬标对象即就是被代理对象
 	private Object target;
 
 	public PayServiceJDKInvocationHandler( Object target) {
		 this.target = target;
 	}
 
	//proxy代理对象
 	@Override
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		 //1.安全检查
		 System.out.println("安全检查");
		 //2.记录⽇志
		 System.out.println("记录⽇志");
 		//3.时间统计开始
 		System.out.println("记录开始时间");
 		//通过反射调⽤被代理类的⽅法
 		Object retVal = method.invoke(target, args);
 		//4.时间统计结束
 		System.out.println("记录结束时间");
 		return retVal;
 	}
 	public static void main(String[] args) {
 		PayService target= new AliPayService();
 		//⽅法调⽤处理器
 		InvocationHandler handler = new PayServiceJDKInvocationHandler(target);
		//创建⼀个代理类:通过被代理类、被代理实现的接⼝、⽅法调⽤处理器来创建
 		PayService proxy = (PayService) Proxy.newProxyInstance(
		 target.getClass().getClassLoader(),new Class[]{PayService.class},handler);
 		proxy.pay();
 	}
}

6.3 CGLIB 动态代理实现

public class PayServiceCGLIBInterceptor implements MethodInterceptor {
 	//被代理对象
	 private Object target;
 
	 public PayServiceCGLIBInterceptor(Object target){
	 	this.target = target;
 	 }
 
	 @Override
	 public Object intercept(Object o, Method method, Object[] args, MethodProxymethodProxy)throws Throwable {
 		 //1.安全检查
		 System.out.println("安全检查");
		 //2.记录⽇志
 		System.out.println("记录⽇志");
		 //3.时间统计开始
 		System.out.println("记录开始时间");
         //通过cglib的代理⽅法调⽤
 		Object retVal = methodProxy.invoke(target, args);
		 //4.时间统计结束
		System.out.println("记录结束时间");
		return retVal;
 	}
 
	 public static void main(String[] args) {
		 PayService target= new AliPayService();
 		PayService proxy= (PayService) Enhancer.create(target.getClass(),
                   new PayServiceCGLIBInterceptor(target));
         proxy.pay();
 	 }
}

6.4 JDK 和 CGLIB 实现的区别

  1. JDK 实现,要求被代理类必须实现接口,之后是通过 InvocationHander 及 Proxy,在运行时动态的在内存中生成了代理对象,该代理对象是通过实现同样的接口实现(类似静态代理接口实现的方式),只是该代理类是在运行期时,动态的织入统一的业务逻辑字节码来完成的
  2. CGLIB 实现,被代理类可以不实现接口,是通过继承被代理类,在运行时动态的生成代理类对象,这种方式实现方式效率高
SpringAOP学习--SpringAOP简介及原理
drhrht的博客
08-02 3908
为了标准化AOPSpring引入了一套AOP顶级API--AOP联盟,用来定义和使用AOP。底层根据配置生成JDK或CGLIB动态代理对象。SpringAOP不是一种新的AOP实现,使用JDK动态代理和CGLIB动态代理实现SpringAOP配置方式核心是Advisor,可以自定义Advisor,也可以通过AspectJ间接定义AdvisorSpringAOP实现遵循了AOP联盟规范,AOP联盟顶级API接口贯穿了整个AOP过程httpshttpshttpshttpshttps。...
SpringAOP的底层实现原理/什么是AOP
qq_41134990的博客
09-06 178
5.从拦截器链中依次获取每一个通知开始进行执行,在执行过程中,为了方便找到下一个通知是哪个,会有一个CglibMethodInvocation的对象,找的时候是从-1的位置依次开始查找并且执行的。aop是ioc的一个扩展功能,先有的ioc再有的aop,只是在ioc的整个流程中新增的一个扩展点而已。3.在执行方法调用的时候,会调用到生成的字节码文件中,直接回找到DynamicAdvisoredInterceptor类中的intercept方法,从此方法开始执行。总:aop概念,应用场景,动态代理。
深入浅析Springaop实现原理
09-02
AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。本文给大家介绍Springaop实现原理,感兴趣的朋友一起学习吧
Springaop原理及各种应用场景
01-27
AOP是AspectOrientedPrograming的简称,面向切面编程。AOP适合于那些具有横切逻辑的应用:如性能监测,访问控制,事务管理、缓存、对象池管理以及日志记录。AOP将这些分散在各个业务逻辑中的代码通过横向切割的方式抽取到一个独立的模块中。AOP 实现的关键就在于AOP框架自动创建的AOP代理,AOP代理则可分为静态代理和动态代理两大类,其中静态代理是指使用 AOP框架提供的命令进行编译,从而在编译阶段就可生成AOP代理类,因此也称为编译
Spring高手之路18——从XML配置角度理解Spring AOP
最新发布
卓越无关环境,保持空杯心态——靡不有初,鲜克有终
05-12 1万+
本文是全面解析面向切面编程的实践指南。通过深入讲解切面、连接点、通知等关键概念,以及通过XML配置实现Spring AOP的步骤。
Spring——AOP原理及流程详解
共勉
11-28 7927
基于5.3.9 版本的Spring源码,对AOP原理及流程详解,AOP是在Bean生成流程中什么位置介入处理的?各个通知方法又是怎么组装的?AOP真的只是动态代理这么简单吗?
图文详解Spring AOP,你学会了吗?
qq_39652397的博客
04-28 2996
如果说 IOC 是 Spring 的核心,那么面向切面编程AOP就是 Spring 另外一个最为重要的核心,需要重点掌握@mikechen 本篇主要会详解以下六点: 1.AOP的定义 2.AOP的作用 3.AOP的应用场景 4.Spring AOP的术语 AOP核心概念 Spring AOP 通知分类 Spring AOP 织入时期 5.Spring AOP三种使用方式 方式1:使用Spring自带的AOP 方式2:使用Aspectj实现切面(普通POJO的实现方式) 方式3:使用As
SpringAOP(图文详解)
热门推荐
lhj520cb的博客
07-16 3万+
Spring实现AOP是代理模式,给调用者使用的实际是已经过加工的对象,你编程时方法体里只写了A,但调用者拿到的对象的方法体却是xAy。x和y总还是需要你来写的,这就是增强。x和y具体在什么时候被调用总还是需要你来规定的,虽然是基于约定的声明这种简单的规定,这就是切点。
图文详解 Spring AOP,看完必懂!
良月柒
03-18 2154
程序员的成长之路互联网/程序员/技术/资料共享关注阅读本文大概需要 4 分钟。来自:blog.csdn.net/duxd185120/article/details/109210224学...
Spring AOP介绍 Spring AOP使用方法
qq_42908340的博客
05-06 595
Spring AOP用法介绍/AOP使用方法概念1.切面组件(Aspect Bean)2.切入点(pointcut)3.通知(Advice)4.目标组件(Target)5.动态代理(AutoProxy)AOP使用方法1.AOP分析2.AOP案例 概念 AOP Aspect Oritened Programming 被称为面向切面编程。 OOP Object Oritened Programming...
Spring AOP + 注解实现统一注解功能
08-27
"Spring AOP + 注解实现统一注解功能" 本文我们通过Spring AOPJava的自定义注解来实现日志的插入功能,该方案对原有业务入侵较...通过本文,我们可以学习到Spring AOPJava注解的使用,并了解日志处理的实现原理
Spring AOP实现原理详解及实例
10-19
主要介绍了Spring AOP实现原理详解及实例的相关资料,需要的朋友可以参考下
Spring AOP实现原理解析
08-28
Spring AOP实现原理解析 Spring AOP(Aspect-Oriented Programming)是一种面向方面编程的技术,它可以将公共行为封装到一个可重用模块中,以减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可...
springAOP的三种实现方式示例代码
08-18
Spring AOP 三种实现方式示例代码 Spring AOP(Aspect-Oriented Programming)是 Spring 框架中的一种面向方面编程技术,主要用于解决横切关注点的问题。AOP 的主要思想是将横切逻辑代码从业务逻辑代码中分离出来,...
Spring AOP 详解
yyhgo_的博客
01-23 6249
Spring AOP 详解
细说Spring——AOP详解(AOP概览)
Cx330_0217的博客
06-23 4335
一、对AOP的初印象 首先先给出一段比较专业的术语(来自百度):在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方 式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个 热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑 的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高 了开发的效率。 然后我们举一个比较容易理解的例子(
SpringAOP超详细图文解释(深入学习笔记可用于面试)
sakura的博客
09-23 1816
记录什么高频面径之SpringAOP底层原理以及对应的开发使用详细讲解;AOP 面向方面编程(Aspect-oriented Programming,151)通过提供关于程序结构的另一种思考方式,补充了面向对象编程。在 OOP 中,模块化的关键单元是类,而在 AOP 中,模块化的单元是方面。方面支持跨多个类型和对象的关注(例如事务管理)的模块化。
SpringAOP详解+快速入门
zhaolk的博客
06-04 2095
本文介绍了 Spring AOP实现原理,并通过实例解析详细阐述了其实现过程。在使用 Spring AOP时,我们需要定义切面类,并为需要实现AOP的方法添加注解。 Spring 会自动将切面逻辑插入到这些方法中,从而实现AOP的功能。
spring aop实现原理
05-14
Spring AOP (Aspect Oriented Programming) 是 Spring 框架中的一个核心模块,它提供了一个非常方便的机制来实现横切关注点的功能,如日志记录、性能统计、安全控制等。 Spring AOP实现原理主要涉及以下几个方面: 1. 静态代理 Spring AOP 底层采用了静态代理的方式来实现 AOP 相关功能。它利用代理类来包装原始对象,并在代理类中添加横切逻辑代码,从而实现对原始对象的增强。 2. 切面(Aspect) 切面是 Spring AOP 中最核心的概念,它定义了横切逻辑的实现方式。在 Spring AOP 中,切面通常是一个 Java 类,它包含了一些通知(Advice)和切点(Pointcut),用来描述横切逻辑的具体实现。 3. 通知(Advice) 通知是切面中的一个方法,它包含了实际的横切逻辑代码。Spring AOP 提供了五种类型的通知: - 前置通知(Before advice):在目标方法执行前执行。 - 后置通知(After returning advice):在目标方法返回后执行。 - 环绕通知(Around advice):在目标方法执行前后都执行。 - 异常通知(After throwing advice):在目标方法抛出异常后执行。 - 最终通知(After finally advice):在目标方法执行后执行,无论是否抛出异常。 4. 切点(Pointcut) 切点是一个表达式,用来匹配目标对象中的方法。Spring AOP 支持多种切点表达式语言,如 AspectJ 表达式、Java 注解等。 5. Advisor Advisor 是 Spring AOP 中的一个概念,它将切点和通知进行了封装,是 Spring AOP 的基本组成单元。 6. 织入(Weaving) 织入是指将切面应用到目标对象中的过程。在 Spring AOP 中,织入可以在编译期、类加载期、运行期三个阶段进行。Spring AOP 默认采用运行期织入的方式,即在目标对象方法调用时动态地将切面代码织入到目标方法的前、后或异常抛出等不同时机。 以上就是 Spring AOP 的基本实现原理。通过静态代理、切面、通知、切点、Advisor 和织入等概念的使用,Spring AOP 实现了对目标对象的增强,实现了横切逻辑的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
写文章

热门文章

  • 手把手教你JDK+IDEA的安装和环境配置 52576
  • Java【String类】的详解 25507
  • Java实现简易版的【图书管理系统】 24980
  • Java中的异常 20247
  • 详解java中的【接口】(关键字implements) 15023

分类专栏

  • 测试 6篇
  • JavaEE 37篇
  • 刷题笔记 27篇
  • 数据结构 15篇
  • JavaSE 23篇
  • 前端学习笔记 7篇
  • MySQL 5篇
  • C语言 16篇

最新评论

  • 动态规划-完全背包问题(纯完全背包、零钱兑换II、组合总数 IV、零钱兑换、完全平方数、单词拆分)、纯多重背包问题

    m0_73797259: 好贴 顶

  • Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

    技能加持ing: 请问有没有比较全面深入的资料推荐啊

  • Java实现简易版的【图书管理系统】

    m0_75220549: 我也好奇这个事情

  • 手把手教你JDK+IDEA的安装和环境配置

    chloesi: 按照教程安装jdk,环境检查好几遍了就是不对,怎么回事啊

  • Spring AOP(AOP概念、组成、Spring AOP实现及实现原理)

    森林公园: 入门介绍不错,但是对 AOP 的实现原理分析不全面、不深入。加油

最新文章

  • Java 面试题之框架
  • Java面试题之线程
  • 常见面试题之计算机网络
2024年4篇
2023年33篇
2022年115篇
2021年1篇

目录

目录

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

快到锅里来呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或 充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

深圳SEO优化公司宝安百度标王大鹏营销网站福田网站推广工具坪山网站搭建宝安百度关键词包年推广坂田网站设计模板盐田外贸网站设计坪地网站制作设计民治网站优化软件坪山网页设计石岩设计网站观澜模板推广福田外贸网站建设大浪网络推广广州网站优化按天计费永湖网站改版深圳模板制作南山网站推广惠州百度竞价福田百度竞价包年推广龙岗外贸网站建设福田关键词排名大浪企业网站改版盐田网站优化推广观澜百度网站优化沙井企业网站改版南联百搜标王福永百度爱采购荷坳企业网站改版广州推广网站歼20紧急升空逼退外机英媒称团队夜以继日筹划王妃复出草木蔓发 春山在望成都发生巨响 当地回应60岁老人炒菠菜未焯水致肾病恶化男子涉嫌走私被判11年却一天牢没坐劳斯莱斯右转逼停直行车网传落水者说“没让你救”系谣言广东通报13岁男孩性侵女童不予立案贵州小伙回应在美国卖三蹦子火了淀粉肠小王子日销售额涨超10倍有个姐真把千机伞做出来了近3万元金手镯仅含足金十克呼北高速交通事故已致14人死亡杨洋拄拐现身医院国产伟哥去年销售近13亿男子给前妻转账 现任妻子起诉要回新基金只募集到26元还是员工自购男孩疑遭霸凌 家长讨说法被踢出群充个话费竟沦为间接洗钱工具新的一天从800个哈欠开始单亲妈妈陷入热恋 14岁儿子报警#春分立蛋大挑战#中国投资客涌入日本东京买房两大学生合买彩票中奖一人不认账新加坡主帅:唯一目标击败中国队月嫂回应掌掴婴儿是在赶虫子19岁小伙救下5人后溺亡 多方发声清明节放假3天调休1天张家界的山上“长”满了韩国人?开封王婆为何火了主播靠辱骂母亲走红被批捕封号代拍被何赛飞拿着魔杖追着打阿根廷将发行1万与2万面值的纸币库克现身上海为江西彩礼“减负”的“试婚人”因自嘲式简历走红的教授更新简介殡仪馆花卉高于市场价3倍还重复用网友称在豆瓣酱里吃出老鼠头315晚会后胖东来又人满为患了网友建议重庆地铁不准乘客携带菜筐特朗普谈“凯特王妃P图照”罗斯否认插足凯特王妃婚姻青海通报栏杆断裂小学生跌落住进ICU恒大被罚41.75亿到底怎么缴湖南一县政协主席疑涉刑案被控制茶百道就改标签日期致歉王树国3次鞠躬告别西交大师生张立群任西安交通大学校长杨倩无缘巴黎奥运

深圳SEO优化公司 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化