【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?

简介: 【Java框架型项目从入门到装逼】第二节 - Spring框架 AOP的丧心病狂解说,你喜欢露娜的月下无限连吗?

继续上一节的内容,多几个jar包:

25.png

aop技术是面向切面编程思想,作为OOP的延续思想添加到企业开发中,用于弥补OOP开发过程中的缺陷而提出的编程思想。AOP底层也是面向对象;只不过面向的不是普通的Object对象,而是特殊的AOP对象。AOP的关注点是组成系统的非核心通用服务模块(比如登录检查等),相对于普通对象,aop不需要通过继承、方法调用的方式来提供功能,只需要在xml文件中以引用的方式,将非核心服务功能引用给需要改功能的核心业务逻辑对象或方法中。最终实现对象的解耦。spring 中ioc技术实现了核心业务逻辑对象之间的解耦(如LoginAction与DaoImpl)


26.jpg

AOP可以说是Spring中最难理解的一个知识点了,你可能网上找了很多资料,也买过很多本书,但都不是很理解到底什么是AOP?我曾经也是琢磨了好久才有了一定的了解。那么,到底怎么讲这个知识点呢。来不及解释了,快上车!听完这个例子,我相信你一定会对AOP有一个非常深刻的理解!

让我们新建一个英雄类:


package com.spring.bean;
public class Hero {
  private String heroName;
  private String type;
  private String description;
  public String getHeroName() {
    return heroName;
  }
  public void setHeroName(String heroName) {
    this.heroName = heroName;
  }
  public String getType() {
    return type;
  }
  public void setType(String type) {
    this.type = type;
  }
  public String getDescription() {
    return description;
  }
  public void setDescription(String description) {
    this.description = description;
  }
  @Override
  public String toString() {
    return "Hero [heroName=" + heroName + ", type=" + type + ", description=" + description + "]";
  }
}

再来个露娜类,继承自英雄类:

27.png


啊啊啊,放错图片了,应该是这个:

28.png


package com.spring.bean;
public class Luna extends Hero{
  /**
   * 秀操作
   */
  public void operation(){
    System.out.println("看我月下无限连!");
  }
  /**
   * 跑路
   */
  public void run(){
    System.out.println("我操,大空了,赶紧跑!");
  }
  /**
   * 发信息
   * @param str
   */
  public void say(String str){
    System.out.println(str);
  }
}

可以看到,露娜类有三个方法,分别是秀操作,跑路和发信息。

再写一个团战类:

package com.spring.test;
import com.spring.bean.Luna;
/**
 * 团战类
 * @author Administrator
 *
 */
public class Battle {
  public void tuan(){
    Luna luna = new Luna();
    luna.say("上去开团!");
    luna.operation();
  }
}


测试代码如下:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
Battle battle = (Battle)context.getBean("Battle");
battle.tuan();


我们用spring把Battle类配上去。

spring-aop.xml

<bean id = 'Battle' class="com.spring.test.Battle"></bean>

运行测试代码:

29.pngimage.png


在团战方法里面,我们新建一个露娜的对象,然后发出信息“上去开团”,接着又秀了一把操作。这是一个比较普通的流程。而事实上,露娜可能需要在团战前就提醒我方队友“等我集合打团”,不要人都没齐,队友就无脑往前冲。OK,我们如何通过代码来实现这个过程呢?很显然,这个过程需要在团战方法执行之前就被执行。这就需要AOP面向切面的技术了。


我们需要写一个类,实现MethodBeforeAdvice接口。

/**
 * Notice 定义一个通知打团的信号 - 团战之前
 * @author Administrator
 *
 */
public class BeforeTuanZhan implements MethodBeforeAdvice{
  @Override
  public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable {
    System.out.print(this.getClass().getName() + " -- ");
    Luna luna = new Luna();
    luna.setHeroName("露娜");
    luna.setType("战士/法师");
    luna.setDescription("月光女神");
    luna.say("等我集合打团!");
  }
}


我们希望这个方法在团战之前就被执行,怎么做呢?没错,就是在XML文件中做如下配置:

<bean id = 'BeforeTuanZhan' class="com.spring.service.BeforeTuanZhan"></bean>
<aop:config>
    <!-- 定义所有可供露娜切入的点(方法) -->
    <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
        <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
        <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
    </aop:config>


execution(* com.spring.test.Battle.*(…))

这句话的含义就是,返回值为任意,com.spring.test包里面的Battle类,这个类里面所有的方法都需要切入。所谓的切入,就是在方法执行前,执行中,发生异常的时候执行某个其他的方法。执行中用的不多,一般就用另外三种情况。


现在,我们重新执行测试代码:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
Battle battle = (Battle)context.getBean("Battle");
battle.tuan();

30.png

现在各位想一下,如果团战打赢了怎么办,是不是马上就该去推塔或者打龙啊,这个时候,如果队友团战打赢了就发呆,那就很坑了。所以呢,你这个时候就得提醒队友下一步该做什么,这个提醒的步骤是在团战方法执行结束后才发生的。


我们需要新建一个AfterTuanZhan类,实现AfterReturningAdvice接口。


/**
 * Notice 定义一个团战结束后的类 - 团战之后
 * @author Administrator
 */
public class AfterTuanZhan implements AfterReturningAdvice{
  @Override
  public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable {
    System.out.print(this.getClass().getName() + " -- ");
    Luna luna = new Luna();
    luna.setHeroName("露娜");
    luna.setType("战士/法师");
    luna.setDescription("月光女神");
    luna.say("进攻敌方防御塔!");
  }
}


配置到spring-aop.xml中:

<bean id = 'AfterTuanZhan' class="com.spring.service.AfterTuanZhan"></bean>
<!-- 定义一个切面 -->
  <aop:config>
    <!-- 定义所有可供露娜切入的点(方法) -->
    <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
        <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
        <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="AfterTuanZhan" pointcut-ref="pointcut"/>
    </aop:config>

现在,我们重新执行测试代码:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
Battle battle = (Battle)context.getBean("Battle");
battle.tuan();


32.png


再来说说万一团战失利的情况,比如露娜断大了咋办,没错,这个时候就是团战发生了异常,我们在Battle类中手动设置一个异常:

/**
 * 团战类
 * @author Administrator
 *
 */
public class Battle {
  public void tuan(){
    Luna luna = new Luna();
    luna.say("上去开团!");
    luna.operation();
    int i = 1 / 0 ;
  }
}


然后,编写TuanZhanException类,实现ThrowsAdvice接口:

/**
 * 定义一个团战异常类,万一出现情况就进入这个类
 * @author Administrator
 *
 */
public class TuanZhanException implements ThrowsAdvice {
  //该方法会在露娜团战出现异常后自动执行
    public void afterThrowing(Method method, Object[] args, 
            Object target, Exception ex){
      System.out.print(this.getClass().getName() + " -- ");
        Luna luna = new Luna();
        luna.run();
    }
}

配置到spring-aop,xml:

<bean id = 'TuanZhanException' class="com.spring.service.TuanZhanException"></bean>
<!-- 定义一个切面 -->
  <aop:config>
    <!-- 定义所有可供露娜切入的点(方法) -->
    <!-- 原则上只要时机正确,任何团战露娜都可以切进去! -->
        <aop:pointcut expression="execution(* com.spring.test.Battle.*(..))" id="pointcut"/>
        <aop:advisor advice-ref="BeforeTuanZhan" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="AfterTuanZhan" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="TuanZhanException" pointcut-ref="pointcut"/>
    </aop:config>

现在,我们重新执行测试代码:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-aop.xml");
Battle battle = (Battle)context.getBean("Battle");
battle.tuan();


33.png

###总结:

#####1. aop面向切面,切的是什么,没错,切的是方法!

#####2. 怎么切,你记好了,就是你先自己规定哪些方法需要切,然后设置切入的方式:方法执行之前做什么,执行之后做什么,如果方法出现异常,又要做什么?另外还有一种方法执行的过程中做什么,只是用的比较少,反正我还没有见过在哪里用了。用的最多的就是发生异常后做什么,比如事务管理。


34.png


#据说露娜要重做,玩个屁,劳资退游吃鸡去了,谢谢。

如果喜欢我的文章,还请点一波关注,谢谢老铁!

相关文章
|
9天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
2天前
|
SQL Java 数据库连接
从理论到实践:Hibernate与JPA在Java项目中的实际应用
本文介绍了Java持久层框架Hibernate和JPA的基本概念及其在具体项目中的应用。通过一个在线书店系统的实例,展示了如何使用@Entity注解定义实体类、通过Spring Data JPA定义仓库接口、在服务层调用方法进行数据库操作,以及使用JPQL编写自定义查询和管理事务。这些技术不仅简化了数据库操作,还显著提升了开发效率。
12 3
|
5天前
|
前端开发 Java 数据库
如何实现一个项目,小白做项目-java
本教程涵盖了从数据库到AJAX的多个知识点,并详细介绍了项目实现过程,包括静态页面分析、数据库创建、项目结构搭建、JSP转换及各层代码编写。最后,通过通用分页和优化Servlet来提升代码质量。
17 1
|
17天前
|
Java 数据库连接 开发者
Spring 框架:Java 开发者的春天
【10月更文挑战第27天】Spring 框架由 Rod Johnson 在 2002 年创建,旨在解决 Java 企业级开发中的复杂性问题。它通过控制反转(IOC)和面向切面的编程(AOP)等核心机制,提供了轻量级的容器和丰富的功能,支持 Web 开发、数据访问等领域,显著提高了开发效率和应用的可维护性。Spring 拥有强大的社区支持和丰富的生态系统,是 Java 开发不可或缺的工具。
|
12天前
|
JavaScript Java 项目管理
Java毕设学习 基于SpringBoot + Vue 的医院管理系统 持续给大家寻找Java毕设学习项目(附源码)
基于SpringBoot + Vue的医院管理系统,涵盖医院、患者、挂号、药物、检查、病床、排班管理和数据分析等功能。开发工具为IDEA和HBuilder X,环境需配置jdk8、Node.js14、MySQL8。文末提供源码下载链接。
|
17天前
|
JSON Java Maven
实现Java Spring Boot FCM推送教程
本指南介绍了如何在Spring Boot项目中集成Firebase云消息服务(FCM),包括创建项目、添加依赖、配置服务账户密钥、编写推送服务类以及发送消息等步骤,帮助开发者快速实现推送通知功能。
46 2
|
3天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
8 0
|
2天前
|
安全 Java 测试技术
Java并行流陷阱:为什么指定线程池可能是个坏主意
本文探讨了Java并行流的使用陷阱,尤其是指定线程池的问题。文章分析了并行流的设计思想,指出了指定线程池的弊端,并提供了使用CompletableFuture等替代方案。同时,介绍了Parallel Collector库在处理阻塞任务时的优势和特点。
|
11天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?
|
1天前
|
存储 安全 Java
Java多线程编程的艺术:从基础到实践####
本文深入探讨了Java多线程编程的核心概念、应用场景及其实现方式,旨在帮助开发者理解并掌握多线程编程的基本技能。文章首先概述了多线程的重要性和常见挑战,随后详细介绍了Java中创建和管理线程的两种主要方式:继承Thread类与实现Runnable接口。通过实例代码,本文展示了如何正确启动、运行及同步线程,以及如何处理线程间的通信与协作问题。最后,文章总结了多线程编程的最佳实践,为读者在实际项目中应用多线程技术提供了宝贵的参考。 ####
下一篇
无影云桌面