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

我的Java-Web进阶--Spring

1.Spring框架概述

2.IOC控制反转(非注解版)

 

IOC的基础操作 

Spring的IoC(Inversion of Control,控制反转)是Spring框架的核心特性之一。它允许对象在创建时由一个调节器对象或服务提供它们的依赖,而不是通过硬编码的方式创建这些依赖。这促进了松耦合的设计,使得应用程序更易于测试和维护。

下面我将按照您的要求介绍如何使用XML配置方式来实现Spring的IoC基础操作,并给出实例代码。

1. 创建相关类

首先,我们创建几个简单的Java类,这些类将作为Spring容器中的Bean。

// User.java
package com.example;public class User {private String name;private int age;private String[] hobbies;// Constructors, getters and setterspublic User() {}public User(String name, int age, String[] hobbies) {this.name = name;this.age = age;this.hobbies = hobbies;}@Overridepublic String toString() {return "User{name='" + name + "', age=" + age + ", hobbies=" + String.join(", ", hobbies) + "}";}
}

2. 添加Spring的XML配置文件

接下来,我们需要创建一个Spring的XML配置文件来定义Bean。这个文件通常位于src/main/resources目录下,命名为applicationContext.xml

<!-- applicationContext.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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><!-- Bean definition for User with constructor arguments --><bean id="user" class="com.example.User"><constructor-arg value="John Doe" type="String"/><constructor-arg value="30" type="int"/><constructor-arg><array><value>Reading</value><value>Hiking</value><value>Coding</value></array></constructor-arg></bean></beans>

在这个配置文件中,我们定义了一个名为user的Bean,它使用了User类的构造函数进行初始化。这里展示了如何为构造函数参数传递Stringint以及String[]类型的值。

3. 注册Bean并使用

最后,我们需要编写一些Java代码来加载Spring上下文并获取Bean实例。

// MainApp.java
package com.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class MainApp {public static void main(String[] args) {// Load Spring configuration fileApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// Retrieve bean from Spring containerUser user = (User) context.getBean("user");// Print out the retrieved beanSystem.out.println(user);}
}

这段代码创建了一个ClassPathXmlApplicationContext实例,它会从类路径下加载applicationContext.xml配置文件。然后,我们使用getBean方法根据ID检索User类型的Bean,并将其打印出来。

XML的Bean对象的参数设置

property

property通过调用类的setter方法进行参数设置

constructor-arg

constructor-arg通过调用构造方法给对象赋值

 

constructor-arg用于集合注入

 Bean对象生命周期

 

 3.IOC控制反转(半注解版)

Spring框架的注解开发是一种基于元数据的配置方式,它允许开发者通过在类、方法或字段上添加注解来替代XML配置。这种方式不仅简化了配置,还使得代码更加清晰和易于维护。以下是几个常用的Spring注解及其用途。

Bean对象池查询

 

Bean对象创建@Component

不写@Component里面的id,默认把类型作为id 

简单的数据类型传参@Value

 对象类型数据传参@Autowired,@Qualified,@Resource

@Autowired

@Autowired 用于自动装配依赖,它可以通过构造函数、setter方法或直接在字段上使用。默认情况下,@Autowired是基于类型进行匹配的。如果容器中有多个相同类型的Bean,而没有指定具体的Bean,则可能会抛出异常。

package com.example;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class ServiceA {private final Repository repository;// 构造器注入@Autowiredpublic ServiceA(Repository repository) {this.repository = repository;}// 使用服务public void useService() {System.out.println("Using " + repository);}
}

@Qualifier

@Qualifier@Autowired 一起使用,当有多个相同类型的Bean时,可以通过名称明确指定要注入哪个Bean。这解决了类型匹配时可能存在的歧义问题。

package com.example;import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;@Component
public class ServiceB {private final Repository specificRepository;// 构造器注入,并使用 @Qualifier 指定特定的 Bean@Autowiredpublic ServiceB(@Qualifier("specificRepository") Repository specificRepository) {this.specificRepository = specificRepository;}// 使用服务public void useService() {System.out.println("Using " + specificRepository);}
}

@Resource

@Resource 是Java EE提供的注解,也支持按名称进行依赖注入。它首先尝试根据名称查找Bean,如果找不到,则回退到按类型查找。因此,它总是优先考虑名字匹配,这与@Autowired的行为有所不同。

package com.example;import javax.annotation.Resource;
import org.springframework.stereotype.Component;@Component
public class ServiceC {// 字段注入,使用@Resource按名称查找@Resource(name="specificRepository")private Repository specificRepository;// 使用服务public void useService() {System.out.println("Using " + specificRepository);}
}

理解:Spring把注册的对象都放到一个对象池里面,通过id匹配

@Autowired注解只通过匹配相同对象类型的方式,创建某一大对象的时候,把相同参数的小对象作为参数传递

@Qualified注解通过匹配id的方式,把匹配到的小对象赋值给大对象

@Resource注解先匹配id,如果匹配不到则匹配相同类型的

Bean对象生命周期@Scope

4.IOC控制反转(全注解版)

Bean对象池查询

 5.AOP面向切面编程

面向切面编程(AOP, Aspect-Oriented Programming)是Spring框架中的一个重要特性,它允许你将横切关注点(如日志记录、事务管理、安全性等)从业务逻辑中分离出来。AOP通过在方法执行前后插入额外的行为来实现这一点,而不需要修改原有代码。使用基于注解的AOP配置可以简化配置过程,并使代码更加清晰和易于维护。

AOP 基于注解的使用方法

1. 引入依赖

首先,确保你的项目包含了必要的Spring AOP依赖。如果你使用的是Maven,可以在pom.xml中添加以下依赖:

<dependencies><!-- Spring AOP --><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.10</version> <!-- 使用与你的项目兼容的版本 --></dependency><!-- 如果需要使用AspectJ编译器 --><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version> <!-- 使用与你的项目兼容的版本 --></dependency>
</dependencies>
2. 启用AOP支持

为了让Spring能够识别和处理AOP注解,你需要在配置类上启用AOP支持。这可以通过在配置类上添加@EnableAspectJAutoProxy注解来完成。

package com.example.config;import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration
@EnableAspectJAutoProxy
public class AppConfig {// 配置类内容
}
3. 创建切面类(重点)

接下来,创建一个切面类,并使用@Aspect注解将其标记为一个切面。在这个类中,你可以定义各种通知(Advice),比如@Before, @After, @Around, @AfterReturning, 和 @AfterThrowing,它们分别对应于方法执行前、后、环绕、成功返回后和抛出异常后。

package com.example.aspect;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {// 定义切入点表达式@Pointcut("execution(* com.example.service.*.*(..))")public void serviceLayer() {}// 在服务层方法执行前记录日志@Before("serviceLayer()")public void logBefore() {System.out.println("Logging before method execution.");}// 在服务层方法执行后记录日志@After("serviceLayer()")public void logAfter() {System.out.println("Logging after method execution.");}
}
4. 定义业务逻辑类

现在,我们可以定义一些业务逻辑类,这些类的方法将会被上面定义的切面所拦截。

package com.example.service;import org.springframework.stereotype.Service;@Service
public class MyService {public void performTask() {System.out.println("Executing task in MyService.");}
}
5. 测试AOP功能

最后,我们编写一个简单的测试类来验证AOP是否按预期工作。

package com.example;import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;import com.example.service.MyService;public class AopTestApp {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);MyService myService = context.getBean(MyService.class);// 调用服务方法,触发AOP通知myService.performTask();}
}
6. 运行结果

当你运行AopTestApp时,你应该会看到如下输出:

Logging before method execution.
Executing task in MyService.
Logging after method execution.

这表明AOP切面已经成功地在MyService#performTask方法执行前后插入了日志记录的通知。

AOP 注解详解

  • @Aspect:用于定义一个类作为切面。
  • @Pointcut:用于定义切入点表达式,标识哪些连接点(通常是方法调用)会被拦截。可以重复使用。
  • @Before:用于定义前置通知,在方法执行之前执行。
  • @After:用于定义后置通知,在方法执行之后执行,无论方法是否抛出了异常。
  • @Around:用于定义环绕通知,可以完全控制方法的执行流程,包括选择是否继续执行方法。
  • @AfterReturning:用于定义返回后通知,在方法正常返回后执行。
  • @AfterThrowing:用于定义异常通知,在方法抛出异常后执行。

切入点表达式

切入点表达式是用来指定哪些方法应该被拦截的规则。AspectJ提供了丰富的语法来定义切入点表达式。例如:

  • execution(* com.example.service.*.*(..)) 匹配com.example.service包下所有类的所有方法。
  • within(com.example.service..*) 匹配com.example.service包及其子包下的所有类的所有方法。
  • @annotation(org.springframework.transaction.annotation.Transactional) 匹配所有带有@Transactional注解的方法。

通过合理使用这些注解和表达式,你可以轻松地为应用程序添加横切关注点,同时保持业务逻辑的清晰和简洁。

通知执行顺序

 

基于XML的配置方式(非重点)

 

 


http://www.mrgr.cn/news/82159.html

相关文章:

  • petalinux2017.4对linux4.9.0打实时补丁
  • 大带宽服务器和普通服务器相比较的优势
  • C++ 设计模式:享元模式(Flyweight Pattern)
  • Leetcode 1254 Number of Closed Islands + Leetcode 1020 Number of Enclaves
  • 推理加速:投机采样经典方法
  • OpenCV-Python实战(13)——图像轮廓
  • CPT203 Software Engineering 软件工程 Pt.2 敏捷方法和需求工程(中英双语)
  • 计算机的错误计算(一百九十七)
  • Kubernetes第二天
  • Vue演练场基础知识(一)
  • Wireshark和科来网络分析系统
  • 掌握大数据处理利器:Flink 知识点全面总结【上】
  • C++ 设计模式:职责链模式(Chain of Responsibility)
  • pyside6总结
  • Docker新手:在tencent云上实现Python服务打包到容器
  • 【Unity3d】C#浮点数丢失精度问题
  • 【文献精读笔记】Explainability for Large Language Models: A Survey (大语言模型的可解释性综述)(二)
  • 1、pycharm、python下载与安装
  • 软件测试期末复习
  • 基于Python的社交音乐分享平台
  • 4.微服务灰度发布落地实践(消息队列增强)
  • C++ 设计模式:命令模式(Command Pattern)
  • AI与药学 | ChatGPT 在临床药学中的有效性以及人工智能在药物治疗管理中的作用
  • UCAS 24秋网络认证技术 CH15 Kerberos复习
  • leetcode之hot100---148排序链表(C++)
  • pg_wal 目录下 wal 日志文件异常累积过大