Spring -学习笔记

文章目录

    • 1. Spring介绍
      • 1.1 Spring的体系结构
    • 2.DI/Ioc(依赖注入/控制反转)
      • 2.1 依赖及注解说明
            • 1. lombok
            • 2. spring-context
      • 2.2 Bean和Spring 上下文的配置方式
            • 方式1:基于`xml文件`的配置
            • 方法2: 基于java注解配置bean
            • 方法3:自动化配置
      • 2.3 Bean的实例化方式
            • 方式1:静态工厂
            • 方式2:实例工厂
    • 3.AOP(面向切面编程)
      • 3.1 AOP术语
      • 3.2 AOP依赖导入
      • 3.3 代理
            • JDK动态代理(基于接口代理)
            • CGLIB代理(基于类继承代理)
            • AOP和代理模式之间的关系
      • 3.4 Spring AOP
            • 基于注解的AOP案例

1. Spring介绍

概念: Spring 是一个开源的企业级应用程序开发框架,它为 Java 应用程序提供了全面的基础设施支持和丰富的功能模块。Spring 的目标是简化 Java 开发,提高开发效率、代码质量和可维护性。

  • Aim: 解决企业级应用开发的复杂性而存在;
  • 核心: Spring的核心是提供一个容器。
    这个容器会创建和管理应用的组件,组件称为Bean,通过这个容器将bean装配在一起,形成一个完整的应用程序。
    容器称为Spring应用上下文;
    将bean组装在一起的行为是通过依赖注入DI的模式实现;
  • 作用:
    • 让Java Bean之间进行更有效的解耦;(DI/Ioc)
    • Spring 支持面向切面编程;(AOP)
    • 整合其他框架和技术; (Hibernate、MyBatis、Spring MVC、Spring Data、Spring Security)
    • 提供了声明式事务管理的机制;
    • 强大的测试支持;

Spring相关的开发模式

  • SSH(Spring-Struts-Hibernate)
    1. Spring框架:Spring作为一个轻量级的容器,负责管理应用程序中的对象、依赖注入、事务管理等。它提供了许多功能,如IoC(控制反转)、AOP(面向切面编程)等,用于简化开发过程和增加代码的可维护性。

    2. Struts框架:Struts是一个基于MVC(Model-View-Controller)设计模式的Web框架。它负责处理HTTP请求、将请求映射到相应的处理器(Action)进行处理,并将处理结果呈现给用户。Struts框架提供了一套可扩展的Action处理机制,用于处理用户请求和管理页面跳转。

    3. Hibernate框架:Hibernate是一个对象关系映射(ORM)框架,用于将数据库中的数据映射到Java对象中。它负责处理数据持久化的细节,包括数据库连接、SQL生成、事务管理等。Hibernate提供了简单的API和查询语言,使得开发人员可以更方便地操作数据库。

//

  • SSM(Spring-SpringMVC-MyBatis)
    1. Spring框架:Spring作为一个轻量级的容器,负责管理应用程序中的对象、依赖注入、事务管理等。它提供了许多功能,如IoC(控制反转)、AOP(面向切面编程)等,用于简化开发过程和增加代码的可维护性。

    2. SpringMVC框架:SpringMVC是一个基于MVC(Model-View-Controller)设计模式的Web框架。它负责处理HTTP请求、将请求映射到相应的处理器(Controller)进行处理,并将处理结果呈现给用户。SpringMVC框架提供了一套灵活的处理器映射机制、数据绑定和视图解析等功能,用于构建Web应用程序的前端控制器。

    3. MyBatis框架:MyBatis是一个持久层框架,用于将数据库操作映射到Java对象中。它通过XML或注解配置,提供了简单的数据访问对象(DAO)的编写方式。MyBatis框架负责数据库连接、SQL执行、结果映射等,使得开发人员可以更方便地操作数据库。

1.1 Spring的体系结构

在这里插入图片描述

1.Core Container(核心容器)

Spring的核心容器是其他模块建立的基础。

  • Beans模块:提供了BeanFactory,是工厂模式的经典实现,Spring将管理对象称为Bean。
  • Core核心模块:提供了Spring框架的基本组成部分,包括IoC和DI功能。
  • Context上下文模块:建立在Core和Beans模块的基础之上,它是访问定义和配置的任何对象的媒介。其中ApplicationContext接口是上下文模块的焦点。
  • Context-support模块:提供了对第三方库嵌入Spring应用的集成支持,比如缓存(EhCache、Guava、JCache)、邮件服务(JavaMail)、任务调度(CommonJ、Quartz)和模板引擎(FreeMarker、JasperReports、速率)。
  • SpEL模块:是Spring 3.0后新增的模块,它提供了Spring Expression Language支持,是运行时查询和操作对象图的强大的表达式语言

2.Data Access/Integration(数据访问/集成)

  • JDBC模块:提供了一个JDBC的抽象层,大幅度地减少了在开发过程中对数据库操作的编码。
  • ORM模块:对流行的对象关系映射API,包括JPA、JDO和Hibernate提供了集成层支持。
  • OXM模块:提供了一个支持对象/ XML映射的抽象层实现,如JAXB、Castor、XMLBeans、JiBX和XStream。
  • JMS模块:指Java消息传递服务,包含使用和产生信息的特性,自4.1版本后支持与Spring-message模块的集成。
  • Transactions事务模块:支持对实现特殊接口以及所有POJO类的编程和声明式的事务管理。

3.Web

  • WebSocket模块:它提供了WebSocket和SockJS的实现,以及对STOMP的支持。
  • Servlet模块:也称为Spring-webmvc模块,包含了Spring的(MVC)和REST Web Services实现的Web应用程序。
  • Web模块:提供了基本的Web开发集成特性,例如:多文件上传功能、使用Servlet监听器来初始化IoC容器以及Web应用上下文。
  • Portlet模块:提供了在Portlet环境中使用MVC实现,类似Servlet模块的功能。

4.其他模块

  • AOP模块:提供了面向切面编程实现,允许定义方法拦截器和切入点,将代码按照功能进行分离,以降低耦合性。
  • Aspects模块:提供了与AspectJ的集成功能,AspectJ是一个功能强大且成熟的面向切面编程(AOP)框架。
  • Instrumentation模块:提供了类工具的支持和类加载器的实现,可以在特定的应用服务器中使用。
  • Messaging模块:Spring 4.0以后新增的模块,它提供了对消息传递体系结构和协议的支持。
  • Test模块:提供了对单元测试和集成测试的支持。

2.DI/Ioc(依赖注入/控制反转)

Spring的作用之一:让Java Bean之间进行更有效的解耦

理解Bean 之间的解耦:
传统的 Java 开发中,对象之间的依赖关系通常是通过直接实例化和引用其他对象来建立的,
这导致了高度的耦合性。---------------------------------------------------------------------------
举例:
public class UserService {private UserDao userDao = new UserDao();public void createUser(User user) {// 使用 userDao 对象进行用户数据的持久化操作userDao.save(user);}
}这里存在两个类:UserService 和 UserDao。
UserService 是一个用户服务类,依赖于 UserDao 来进行用户数据的持久化操作。-------------------------------------------------------------------------------------------
UserService 类在自己的代码中直接创建了一个 UserDao 对象,并将其作为成员变量进行引用。
这种方式存在的问题:
1. Service 类与具体的 User 类紧密耦合在一起,User类如果发生改变,service也需要修改。
2. service如果被使用,还需要额外管理UserDao对象的生命周期。
3. 进行测试项目时,无法将service单独进行测试。

概念

IOC(Inversion of Control)和 DI(Dependency Injection)是紧密相关的概念,主要用于解耦对象之间的依赖关系,提高代码的灵活性、可维护性和可测试性。
//
IOC(控制反转) 是一种设计原则,“对象的控制权的转移”

  • 指的是将对象的创建和依赖关系的管理交给容器来控制,而不是由应用程序代码显式地创建和管理对象(在传统的编程模型中,应用程序代码负责创建和管理对象,而在IOC模式下,这种控制权被转移到了容器中)。

DI(依赖注入) 是IOC的一种实现方式,“描述对象之间的依赖关系是通过注入的方式解决”

  • 指通过容器将依赖关系注入到对象中。
    在依赖注入中,对象不再负责自己的依赖关系的创建,而是通过构造函数、属性或方法参数等方式接收依赖对象。
    依赖注入可以通过接口、注解或配置来实现,目的是实现对象之间的解耦和灵活性。

2.1 依赖及注解说明

1. lombok
<!--        简化实体类的开发,通过注解自动化生成Java类的样板代码,如Getter、Setter、构造函数、equals()和hashCode()等方法--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.28</version></dependency>

创建一个实体类,使用@Data注解 自动生成get set 等方法

package com.imooc.pojo;import lombok.Data;@Data
public class Student {private long id;private String name;private int age;
}

测试类中直接创建Student对象并赋值。

package com.imooc.test;import com.imooc.pojo.Student;public class UserDemo {public static void main(String[] args) {Student student = new Student();student.setId(1);student.setName("tudou");student.setAge(2);System.out.println(student);}
}

在这里插入图片描述

2. spring-context

spring-context模块是Spring框架的核心模块之一,提供了IoC(控制反转)容器的功能,以及其他与应用程序上下文相关的特性。

<!--        Spring上下文依赖--><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.0.11.RELEASE</version></dependency>

2.2 Bean和Spring 上下文的配置方式

方式:

  1. 基于xml文件;
  2. 基于java注解的配置;
  3. 自动化配置
方式1:基于xml文件的配置

1.在resource下创建一个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"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
</beans>

创建实体类

package com.imooc.pojo;import lombok.Data;@Data
public class Student {private long id;private String name;private int age;
}

在xml中引入实体类

id:对象名
class:对象的模板类(所有交给Ioc管理的类,必须有无参构造方式)
成员变量通过property标签赋值

  • name:成员变量名
  • value:成员变量值(基本数据类型)
  • ref:将ioc中的另一个bean赋值给当前bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="student" class="com.imooc.pojo.Student"><property name="id" value="1"></property><property name="name" value="zhangsan"></property><property name="age" value="56"></property><property name="address" ref="address"></property></bean><bean id="address" class="com.imooc.pojo.Address"><property name="city" value="beijing"></property><property name="home" value="qinghau"></property></bean>
</beans>

测试

public class UserDemo {public static void main(String[] args) {Student student = new Student();student.setId(1);student.setName("tudou");student.setAge(2);System.out.println(student);//加载配置文件ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");Student student1 = (Student)classPathXmlApplicationContext.getBean("student");System.out.println(student1);}
}

在这里插入图片描述

方法2: 基于java注解配置bean
注解说明
@Configuration表示当前类是一个配置类,相当于之前的spring.xml文件
@Bean返回一个由Spring管理的bean对象。
package com.imooc.config;import com.imooc.pojo.Address;
import com.imooc.pojo.Student;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class StudentConfig {@Beanpublic Student student(){Student student = new Student();student.setId(2);student.setName("lisi");student.setAge(66);student.setAddress(address());return student;}@Beanpublic Address address(){Address address = new Address();address.setCity("南京");address.setHome("家");return address;}
}
import com.imooc.config.StudentConfig;
import com.imooc.pojo.Address;
import com.imooc.pojo.Student;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class StudentDemo {public static void main(String[] args) {// 创建基于注解的应用程序上下文AnnotationConfigApplicationContext acac = new AnnotationConfigApplicationContext(StudentConfig.class);// 获取配置的beanStudent bean = acac.getBean(Student.class);
//        Address bean1 = acac.getBean(Address.class);// 使用beanSystem.out.println(bean);}
}

在这里插入图片描述

方法3:自动化配置

@Component 注解通常与其他相关的注解(如 @Service、@Repository、@Controller 等)一起使用,用于标记不同层次或类型的组件,以告诉 Spring 框架要扫描哪些包来寻找被注解的组件。这样,Spring 容器会自动实例化管理这些组件,以供应用程序使用。

注解说明
@Component将一个类标记为 Spring 托管的组件,Spring 容器会自动扫描并实例化这些组件,并将它们纳入到应用程序上下文中
@Service标记服务层组件,表示该组件用于处理业务逻辑。通常,服务层组件被用于封装业务逻辑,处理数据的获取、转换、计算和操作等任务。
@Repository标记持久层组件,表示该组件用于封装数据访问逻辑。通常,持久层组件用于与数据库或其他数据存储进行交互,执行数据的读取、写入、更新和删除等操作。
@Controller用于标记控制层组件,表示该组件用于处理请求和响应。通常,控制层组件接收用户请求,调用适当的服务层组件处理请求,并返回响应给用户。
//创建配置类
import com.imooc.pojo.Student;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;@Component("student4")
@Service
public class StudentService {public Student createStudentt(){Student student = new Student();student.setName("画虎");return student;}
}

xml自动化配置
在spring.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:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><!--注解组件扫描,扫描指定的基本包及其子包下的类,识别使用@Component注解--><context:component-scan base-package="com.imooc"></context:component-scan></beans>

测试

public class StudentDemo4 {public static void main(String[] args) {ClassPathXmlApplicationContext classPathXmlApplicationContext = new ClassPathXmlApplicationContext("spring.xml");StudentService studentService= classPathXmlApplicationContext.getBean(StudentService.class);Student studentt = studentService.createStudentt();System.out.println(studentt);}
}

在这里插入图片描述

java注解自动化扫描

package com.imooc.config;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;//@Configuration声明加载配置类,@ComponentScan指定要扫描的包和子包
@Configuration
@ComponentScan(basePackages = "com.imooc")
public class StudentAutoConfig {}
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class StudentDemo5 {public static void main(String[] args) {// 创建一个注解配置的应用上下文AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(StudentAutoConfig.class);// 从应用上下文中获取 StudentService 的实例StudentService bean = annotationConfigApplicationContext.getBean(StudentService.class);// 调用 StudentService 的 createStudentt() 方法创建一个学生对象Student studentt = bean.createStudentt();// 打印学生对象System.out.println(studentt);}
}

在这里插入图片描述

2.3 Bean的实例化方式

方式1:静态工厂

要求用户创建一个静态工厂的方法来创建bean的实例,其bean配置中的class属性所指的不再是bean的实现类,而是静态工厂类。

  • 使用factory-method属性指定创建的静态工厂方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

方式2:实例工厂

在工厂类中,直接创建Bean实例;
在配置文件中,先创建配置工厂
再创建实例工厂指向该配置工厂,再指定方法
在这里插入图片描述

<!--    配置工厂--><bean id="studentFactory" class="com.imooc.factory.StudentFactory"/>
<!--    实例工厂--><bean id="student3"  factory-bean="studentFactory" factory-method="createStudents"></bean>

在这里插入图片描述

3.AOP(面向切面编程)

AOP(面向切面编程)是一种软件开发的编程范式,它的目的是通过将横切逻辑与核心业务逻辑分离,以提高代码的模块性、可维护性和可重用性。
作用:

  • 简化代码:把方法中固定位置的重复代码抽取出来,让被抽取的方法更专注于实现自己的核心业务;

Reason:
在传统的业务处理代码中,通常都会进行事务处理日志记录等操作。

  • 使用OOP(面向对象)以通过组合或者继承的方式来达到代码的重用,但如果要实现某个功能(如日志记录),同样的代码仍然会分散到各个方法中
  • 如果想要关闭某个功能,或者对其进行修改,就必须要修改所有的相关方法。这不但增加了开发人员的工作量,而且提高了代码的出错。

/
AOP采取横向抽取机制,将分散在各个方法中的重复代码提取出来,然后在程序编译或运行时,再将这些提取出来的代码应用到需要执行的地方。

在这里插入图片描述

3.1 AOP术语

一文弄懂AOP概念

关键字解释方法
Aspect切面用于封装横切关注点的类(也称封装通知方法的类)//封装完之后,一个横切关注点表示一个通知方法。
Joinpoint连接点逻辑概念,抽取横切关注点的位置
Pointcut切入点定位连接点的方式
Advice通知切面在特定连接点执行的代码
Weaving织入切面应用到目标对象中的过程
Proxy代理通知应用到目标对象,被动态创建的对象

3.2 AOP依赖导入

        <dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.0.11.RELEASE</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.11.RELEASE</version></dependency>

3.3 代理

在AOP(面向切面编程)中,代理是实现切面功能的关键机制。

  • 代理对象是在目标对象周围创建的,它将目标对象包装起来,并拦截对目标对象的方法调用。通过代理,AOP能够实现横切关注点的分离,将与核心业务逻辑无关的横切关注点(如日志记录、事务管理、安全性检查等)从目标对象中抽离出来。

代理对象和目标对象的关系
举例:每个员工去老板办公室和老板交谈,老板首先要确认是不是内部员工,代理的作用相当于是一个工卡,来帮助老板快速识别内部员工。
//具体:每个员工要去老板办公室和老板交谈时,首先需要通过工卡验证身份。工卡(代理对象)会拦截员工的访问请求,并对员工的身份进行验证。只有通过验证的员工(合法的方法调用)才能继续与老板(目标对象)进行交谈。工卡(代理对象)在验证身份的同时,还可以执行其他额外的任务,例如日志功能:记录员工的访问时间、统计员工的访问次数等。

Spring AOP 的两种代理模式

JDK动态代理:

  • JDK动态代理是基于接口的代理模式。
    当目标对象实现了至少一个接口时,Spring会使用JDK动态代理来创建代理对象。JDK动态代理利用Java的反射机制,在运行时动态地创建代理对象。代理对象实现了目标对象相同的接口,并在方法调用前后插入横切逻辑。JDK动态代理要求目标对象实现接口,因此它更适用于基于接口的代理场景。

CGLIB代理:

  • CGLIB代理是基于类继承的代理模式。
    当目标对象没有实现任何接口时,或者你希望绕过接口的限制时,Spring会使用CGLIB代理来创建代理对象。CGLIB它通过创建目标对象的子类来实现代理。代理对象继承了目标对象的类,并重写了目标对象的方法,在方法调用前后添加横切逻辑。CGLIB代理不要求目标对象实现接口,因此更加灵活,适用于更广泛的代理场景。

//注意:使用JDK动态代理类的对象必须实现一个或多个接口。

JDK动态代理(基于接口代理)

实现步骤:

  1. 定义目标接口(其中包含要被代理的方法),定义目标接口的实现类;
  2. 创建一个代理类(实现InvocationHandler接口),该类负责拦截方法调用并添加额外的逻辑;
  3. 创建代理对象(使用Proxy类中的newProxyInstance方法);
  4. 通过代理对象调用目标接口的方法;
//1. 定义目标接口
public interface Employee {void talkToBoss();
}
------------------------------------------------------------
//2.定义目标接口的实现类
public class EmployeeImpl implements Employee{public void talkToBoss() {System.out.println("我说员工,和老板说话了");}
}//目标接口的另一个实现类
public class EmployeeImpl2 implements Employee{public void talkToBoss() {System.out.println("找老板发工资");}
}----------------------------------------------------------------import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;//2.定义代理类
public class EmployeeProxy implements InvocationHandler {//声明目标接口public Employee employee;//创建代理方法public Object createProxy(Employee employee){this.employee=employee;//2.1 类加载器ClassLoader classLoader = EmployeeProxy.class.getClassLoader();//2.2 被代理对象实现所有接口Class[] classes = employee.getClass().getInterfaces();//2.3 使用代理类,进行增强,返回的是代理后的对象return Proxy.newProxyInstance(classLoader,classes,this);}//所有的动态代理方法调用,都会交由invoke()方法处理//proxy:被代理后的方法//method:要被执行的方法信息(反射)//args:执行方法需要的参数public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//在方法前添加额外逻辑System.out.println("确认身份");//调用目标方法Object invoke = method.invoke(employee, args);//在方法后添加逻辑System.out.println("交谈完毕");return invoke;}
}
---------------------------------------------------------
//3.测试
public class Test {public static void main(String[] args) {//3.1 创建代理对象EmployeeProxy employeeProxy = new EmployeeProxy();//3.2 创建目标对象 //员工1找老板EmployeeImpl employee = new EmployeeImpl();//3.3执行方法Employee proxy = (Employee) employeeProxy.createProxy(employee);proxy.talkToBoss();//员工2找老板EmployeeImpl2 employee2 = new EmployeeImpl2();Employee proxy1 = (Employee) employeeProxy.createProxy(employee2);proxy1.talkToBoss();}
}

在这里插入图片描述

CGLIB代理(基于类继承代理)

步骤

  1. 添加依赖;
  2. 创建目标类(将被代理)
  3. 编写拦截器类
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;// 定义目标类
class Employee {public void talkToBoss() {System.out.println("与老板交谈");}
}// 实现MethodInterceptor接口的代理处理器类
class EmployeeInterceptor implements MethodInterceptor {@Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {// 在目标方法执行前添加额外逻辑System.out.println("确认员工身份");// 调用目标方法Object result = proxy.invokeSuper(obj, args);// 在目标方法执行后添加额外逻辑System.out.println("交谈完毕");return result;}
}public class Main {public static void main(String[] args) {// 创建Enhancer对象Enhancer enhancer = new Enhancer();// 设置目标类enhancer.setSuperclass(Employee.class);// 设置代理处理器enhancer.setCallback(new EmployeeInterceptor());// 创建代理对象Employee proxy = (Employee) enhancer.create();// 通过代理对象调用目标方法proxy.talkToBoss();}
}
AOP和代理模式之间的关系

代理模式

  • 是一种结构设计模式,通过创建一个代理对象来控制原始对象的访问,旨在不改变原始对象的情况下,对其进行增强和控制访问。

AOP

  • 一种编程范式,旨在通过横切关注点(日志、事务等)从核心业务逻辑中分离出来,实现代码的模块化和重用。
  • 代理模式 可以用作实现AOP的一种技术手段

3.4 Spring AOP

AspectJ:基于java的AOP框架;

  • 基于xml
  • 基于注解

基于注解的AspectJ

注解作用
@Aspect:将一个类标记为切面类
@Pointcut:定义切点,指定在哪些连接点上应用切面。
@Before:定义前置通知,在目标方法执行之前执行。
@After:定义后置通知,在目标方法执行之后(包括异常情况)执行。
@AfterReturning:定义返回通知,在目标方法正常返回后执行。
@AfterThrowing:定义异常通知,在目标方法抛出异常时执行。
@Around:定义环绕通知,在目标方法执行前后执行,并可以控制目标方法的执行过程。
@EnableAspectJAutoProxy:启用AspectJ自动代理,用于自动创建代理对象并将切面织入目标对象。

通知:每一个横切关注点,在切面上的实现通过通知方法实现。

通知类型说明
前置通知在目标方法前执行
后置通知在目标方法最终结束后执行(包括正常返回和异常返回)
返回通知目标方法成功结束之后
异常通知目标方法异常结束之后
环绕通知使用try–catch–finally结构环绕整个目标方法,包括上边四种的位置

AOP注意事项

  • 切面类和目标类都需要交给IOC容器管理;
  • 切面类通过@Aspect注解表示为一个切面
  • 在spring配置文件中设置<aop:aspectj-autoproxy开启基于注解的AOP
基于注解的AOP案例

<!--注解组件扫描,扫描指定的基本包及其子包下的类,识别使用@Component注解--><context:component-scan base-package="com.imooc"></context:component-scan>
<!--    开启基于注解的AOP--><aop:aspectj-autoproxy/>
package com.imooc.aop.BETalkPoxy;//1. 定义目标接口
public interface Employee {void talkToBoss();
}------------------------------------------------
package com.imooc.aop.BETalkPoxy;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;//2.定义目标接口的实现类
@Component
public class EmployeeImpl implements Employee{public void talkToBoss() {System.out.println("我说员工,和老板说话了");}
}--------------------------------------------------------
package com.imooc.aop.aspect;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
//3.定义切面
//日志切面  @component组件类 @Aspect 切面类标识
@Component
@Aspect
public class LoggingAspect {//定位到目标对象某一个方法中 public void方法的返回类型@Before("execution(public void com.imooc.aop.BETalkPoxy.EmployeeImpl.talkToBoss())")public void beforeAdviceMethod(){System.out.println("LoggingAspect 前置通知 记录日志开启");}
}---------------------------------------------
//4.测试package com.imooc.test;import com.imooc.aop.BETalkPoxy.Employee;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class EmployeeAopTest {public static void main(String[] args) {ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");Employee bean = (Employee) context.getBean(Employee.class);bean.talkToBoss();}}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/86657.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Nginx详解 第三部分:Nginx高级配置(附配置实例)

Part 3 一、网页的状态页二、Nginx第三方模块2.1 echo 模块 三、变量3.1 内置变量3.1.1 常用内置变量3.1.2 举个例子 3.2 自定义变量 四、自定义访问日志 (优化)4.1 自定义访问日志的格式4.2 自定义json 格式日志 五、Nginx压缩功能&#xff08;重要&#xff09;六、HTTPS 功能…

Android RecyclerView 之 列表宫格布局的切换

前言 RecyclerView 的使用我就不再多说&#xff0c;接下来的几篇文章主要说一下 RecyclerView 的实用小功能&#xff0c;包括 列表宫格的切换&#xff0c;吸顶效果&#xff0c;多布局效果等&#xff0c;今天这篇文章就来实现一下列表宫格的切换&#xff0c;效果如下 一、数据来…

香港全新的虚拟资产服务商发牌制度

香港证监会2023年2月20日通告&#xff0c;原有虛擬資產交易平台如要符合資格參與當作為獲發牌的安排&#xff0c;必須在2023 年6 月1 日至2024 年2 月29 日期間(即由2023 年6 月1 日37起計九個月內)內&#xff0c;根據《打擊洗錢條例》下的虛擬資產服務提供者制度在網上提交完全…

中文乱码处理

&#x1f600;前言 中文乱码处理 &#x1f3e0;个人主页&#xff1a;尘觉主页 &#x1f9d1;个人简介&#xff1a;大家好&#xff0c;我是尘觉&#xff0c;希望我的文章可以帮助到大家&#xff0c;您的满意是我的动力&#x1f609;&#x1f609; 在csdn获奖荣誉: &#x1f3c…

揭秘视频号创收计划:松松一个月赚1300+

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 这是卢松松一个月视频号的收益&#xff0c;1300元。自从视频号在五月份推出创作者分成计划以来&#xff0c;许许多多的视频号创作者开始获得了一些收益&#xff0c;这绝对是一项挺不错的进展。 目前…

iOS App签名与重签名:从开发者证书到重新安装运行

前文回顾&#xff1a; iOS脱壳技术&#xff08;二&#xff09;&#xff1a;深入探讨dumpdecrypted工具的高级使用方法 iOS逆向&#xff1a;越狱及相关概念的介绍 在本文中&#xff0c;我们将详细介绍iOS应用的签名过程&#xff0c;包括开发者证书的种类、证书与App ID、Provisi…

原生web实现不固定列数的表格、随机列、document、querySelector、forEach、hasOwnProperty、call、includes

文章目录 效果图公共样式第一种解决方案(不推荐)第二种解决方案(强烈推荐) 效果图 公共样式 .d_f {display: flex; }.flex_1 {flex: 1; }.jc_sb {justify-content: space-between; }.ai_c {align-items: center; }.bc_ccc {background-color: #cccccc; }/* ------------paddin…

突破边界:文本检测算法的革新与应用前景

突破边界&#xff1a;文本检测算法的革新与应用前景 1.文本检测理论篇&#xff08;文本检测方法介绍&#xff09; 文本检测任务是找出图像或视频中的文字位置。不同于目标检测任务&#xff0c;目标检测不仅要解决定位问题&#xff0c;还要解决目标分类问题。 文本在图像中的…

【操作记录】CLion 中引入 Gurobi 并使用 C++ 编程

文章目录 一、前言二、具体操作2.1 创建项目2.2 修改编译工具2.3 修改 CMakeLists.txt2.4 修改 main.cpp2.5 运行测试 一、前言 虽然C编程大部分人都会选择使用VS&#xff0c;但是作为 IDEA 的长期用户&#xff0c;我还是比较习惯 JetBrains 风格的编译器&#xff0c;所以就选…

华为质量管理:从产品质量到用户体验,Kano模型成为新方向

目录 前言 华为质量管理的四个阶段 基于 IPD 如何做质量管理呢&#xff1f; CSDN相关课程 作者简介 前言 今天继续来谈谈华为流程体系中的质量管理过程。 通常来说质量具体是指产品的质量&#xff0c;也就是产品的使用价值及其属性。 产品再细分的话可以分为三个层次&a…

python 模块openpyxl 读取写入.xlsx文件

Python操作Excel的模块有很多&#xff0c;并且各有优劣&#xff0c;不同模块支持的操作和文件类型也有不同。下面是各个模块的支持情况&#xff1a; xlrd&#xff1a;xlrd 读取.xls文件xlwings&#xff1a;xlwings 读取写入Excel文件xlwt&#xff1a;xlwt 写入.xls文件 一、…

Dubbo源码环境搭建

背景 Dubbo 作为一款微服务框架&#xff0c;最重要的是向用户提供跨进程的 RPC 远程调用能力。如上图所示&#xff0c;Dubbo 的服务消费者&#xff08;Consumer&#xff09;通过一系列的工作将请求发送给服务提供者&#xff08;Provider&#xff09;。 为了实现这样一个目标&a…