Java后端学习系列(8):Spring框架基础入门

该文章已生成可运行项目,

Java后端学习系列(8):Spring框架基础入门

前言

在前面的学习中,我们掌握了Servlet与JSP这些Java Web开发的基础技术,能够构建出简单的Web应用程序了。而Spring框架作为Java后端开发领域极具影响力且广泛应用的框架,它为我们提供了一套更加高效、便捷且灵活的开发模式,能极大地提升开发效率、降低代码耦合度。本期我们就来开启Spring框架基础入门的学习之旅,进一步深化我们的Java后端开发能力。本系列共15期,持续为大家解锁更多实用知识。

一、Spring的基本概念与核心模块介绍

1.1 基本概念

Spring是一个开源的、轻量级的Java开发框架,它致力于解决企业级应用开发中的复杂性问题,通过提供一系列的功能模块和设计模式,帮助开发者更轻松地构建出高质量、可维护且易于扩展的Java应用程序。它采用了控制反转(IoC)和面向切面编程(AOP)等核心思想,改变了传统Java应用的开发方式,让代码的依赖关系更加清晰,模块之间的耦合度更低。

1.2 核心模块

  • Spring Core:这是Spring框架的基础核心模块,提供了控制反转(IoC)容器的实现,负责管理对象的创建、配置以及生命周期等,是整个Spring框架的基石,让对象之间的依赖关系能够通过配置进行灵活管理,而不是在代码中硬编码。
  • Spring Context:构建在Spring Core之上,提供了一种框架式的对象访问方式,比如可以通过配置文件或者注解等方式来获取和管理Spring容器中的对象,还包含了国际化、事件传播等功能,增强了Spring在企业级应用场景中的实用性。
  • Spring AOP:面向切面编程模块,允许开发者将一些横切关注点(如日志记录、事务管理、安全验证等)从业务逻辑代码中分离出来,以切面的形式进行统一管理和织入到目标对象的方法执行过程中,使得业务代码更加专注于核心业务逻辑,提高代码的可维护性和复用性。
  • Spring Data Access/Integration:主要用于处理数据访问相关的事务,涵盖了对各种数据库(如JDBC、Hibernate、MyBatis等)的支持,提供了统一的操作接口和便捷的数据库访问方式,方便开发者进行数据的持久化操作以及事务管理等工作。
  • Spring Web:专注于Web开发领域,基于Servlet API构建,提供了便捷的方式来开发Web应用,比如可以方便地处理HTTP请求、响应,实现Web层的路由、参数绑定等功能,并且与Spring框架的其他模块能够很好地集成,是开发Java Web应用的得力助手。

二、Spring IoC(控制反转)原理与实践

2.1 原理

传统的Java应用中,对象之间的依赖关系通常是由开发者在代码中主动创建和管理的,比如在一个类中直接通过new关键字创建另一个类的实例来使用。而Spring IoC则将这种对象创建和依赖管理的控制权反转了过来,由Spring容器来负责创建对象,并根据配置将对象之间的依赖关系进行注入。

具体来说,Spring容器会读取配置信息(可以是XML配置文件或者基于注解的配置),分析对象之间的依赖关系,先创建出所有需要的对象,然后将依赖的对象注入到对应的对象中,使得对象在使用时已经具备了所需的依赖,而无需自己去创建。例如,有一个UserService类依赖于UserRepository类,Spring容器会在创建UserService时,自动将UserRepository的实例注入进去。

2.2 实践

首先,我们可以通过XML配置方式来实现IoC。假设我们有以下两个简单的类:

public class UserRepository {
    public void saveUser() {
        System.out.println("保存用户信息");
    }
}

public class UserService {
    private UserRepository userRepository;

    public void setUserRepository(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    public void addUser() {
        userRepository.saveUser();
    }
}

在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/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="userRepository" class="com.example.UserRepository"/>
    <bean id="userService" class="com.example.UserService">
        <property name="userRepository" ref="userRepository"/>
    </bean>
</beans>

然后在测试代码中获取Spring容器并使用对象:

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringIocTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserService userService = (UserService) context.getBean("userService");
        userService.addUser();
    }
}

现在更常用的是基于注解的方式,比如使用@Component@Autowired等注解:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class UserRepository {
    public void saveUser() {
        System.out.println("保存用户信息");
    }
}

@Component
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public void addUser() {
        userRepository.saveUser();
    }
}

在启动类或者配置类(可以使用@Configuration注解标记)中配置扫描包路径,让Spring容器能发现这些注解标记的类:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@ComponentScan("com.example")
public class AppConfig {
}

然后同样在测试代码中获取并使用对象:

import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class SpringIocAnnotationTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = (UserService) context.getBean("userService");
        userService.addUser();
    }
}

三、Spring AOP(面向切面编程)的基础应用

3.1 概念

在实际的应用开发中,有很多功能是贯穿于多个业务模块的,比如日志记录,我们希望在每个业务方法执行前后都记录相应的日志信息;又比如事务管理,要确保一组相关的数据库操作要么全部成功要么全部失败。这些横切关注点如果分散在各个业务代码中,会使得业务逻辑变得复杂且难以维护。

Spring AOP就是解决这个问题的有效手段,它允许我们定义切面,将这些横切关注点的逻辑提取出来,然后在合适的时机(比如方法执行前、执行后、抛出异常时等)织入到目标业务方法中,使得业务代码只专注于核心业务逻辑,而这些公共的功能由切面统一处理。

3.2 应用示例

假设我们要为业务方法添加简单的日志记录功能,首先定义一个切面类:

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        System.out.println("方法 " + joinPoint.getSignature().getName() + " 即将执行");
    }
}

在上述代码中,@Aspect注解表明这是一个切面类,@Before注解指定了在目标方法执行前要执行的逻辑,这里的execution(* com.example.service.*.*(..))是一个切点表达式,表示匹配com.example.service包下所有类的所有方法。

然后同样需要在配置类中配置扫描切面类所在的包路径(如果使用注解方式配置Spring),确保Spring容器能识别并应用这个切面。例如:

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
}

这样,当业务方法执行时,就会自动触发切面中定义的日志记录逻辑,在方法执行前输出相应的日志信息了。

四、简单的Spring应用示例搭建

下面我们来搭建一个简单的包含用户管理功能的Spring应用示例,整合前面所学的IoC和AOP知识:

  1. 创建实体类
public class User {
    private String username;
    private String password;

    // 构造函数、Getter和Setter方法省略
}
  1. 创建数据访问层(Repository)接口和实现类
import org.springframework.stereotype.Repository;

import java.util.ArrayList;
import java.util.List;

@Repository
public class UserRepositoryImpl implements UserRepository {
    private List<User> userList = new ArrayList<>();

    @Override
    public void save(User user) {
        userList.add(user);
    }

    @Override
    public User findByUsername(String username) {
        for (User user : userList) {
            if (user.getUsername().equals(username)) {
                return user;
            }
        }
        return null;
    }
}

interface UserRepository {
    void save(User user);
    User findByUsername(String username);
}
  1. 创建业务逻辑层(Service)接口和实现类,并使用IoC注入依赖
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserRepository userRepository;

    @Override
    public void register(User user) {
        userRepository.save(user);
    }

    @Override
    public User login(String username, String password) {
        User user = userRepository.findByUsername(username);
        if (user!= null && user.getPassword().equals(password)) {
            return user;
        }
        return null;
    }
}

interface UserService {
    void register(User user);
    User login(String username, String password);
}
  1. 创建Web层(Controller,这里简单示意,假设基于Spring Web相关技术后续扩展)
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;

    @RequestMapping("/register")
    public ModelAndView register(@RequestParam("username") String username,
                                 @RequestParam("password") String password) {
        User user = new User(username, password);
        userService.register(user);
        ModelAndView modelAndView = new ModelAndView("register_success");
        modelAndView.addObject("user", user);
        return modelAndView;
    }

    @RequestMapping("/login")
    public ModelAndView login(@RequestParam("username") String username,
                              @RequestParam("password") String password) {
        User user = userService.login(username, password);
        ModelAndView modelAndView = new ModelAndView();
        if (user!= null) {
            modelAndView.setViewName("login_success");
            modelAndView.addObject("user", user);
        } else {
            modelAndView.setViewName("login_failure");
        }
        return modelAndView;
    }
}
  1. 配置Spring相关配置(可以是XML或者基于注解方式,这里以注解为例)
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;

@Configuration
@ComponentScan("com.example")
@EnableAspectJAutoProxy
public class AppConfig {
}
  1. 创建对应的JSP页面(如register_success.jsplogin_success.jsplogin_failure.jsp等,简单展示相应信息)
    示例register_success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>注册成功</title>
</head>
<body>
    <h1>用户 ${user.username} 注册成功!</h1>
</body>
</html>

通过这样一个简单的示例,我们整合了Spring的多个核心功能,构建出了一个具备基本用户管理功能的应用框架,后续可以在此基础上进一步扩展和完善功能。

五、下一步学习建议

  1. 深入实践:基于上述示例,继续完善功能,比如增加用户信息修改、删除等操作,深入体会Spring框架在实际项目中的应用,尤其是IoC和AOP在解耦代码、管理横切关注点方面的优势。
  2. 学习拓展模块:进一步了解Spring框架的其他拓展模块,如Spring Security(用于安全认证和授权)、Spring Cloud(用于构建分布式系统、微服务架构等),拓宽知识面,为应对更复杂的开发场景做准备。
  3. 性能优化:研究在Spring应用中如何进行性能优化,比如合理配置Spring容器、优化对象创建和依赖注入的过程、减少不必要的AOP切面等,提升应用的整体性能表现。

下期预告

《Java后端学习系列(9):Spring Boot基础入门》

  • Spring Boot的基本概念与优势
  • 快速搭建Spring Boot项目
  • Spring Boot的自动配置原理
  • 简单的Spring Boot应用示例展示

Spring框架是Java后端开发的重要利器,希望大家通过不断实践和学习,深入掌握它的各项功能,在开发中充分发挥其优势。如果在学习过程中有任何疑问或者心得,欢迎在评论区分享交流,我们下期再见。

本文章已经生成可运行项目
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值