Java Bean 与 Spring 详解

Java Bean 和 Spring 框架的结合是现代 Java 开发的核心。

1. Java Bean 深入剖析

Java Bean 是一种特殊的 Java 类,遵循一系列约定,以方便被框架和工具使用。 这些约定不仅仅是简单的 getter 和 setter。

  • 无参构造器: 这是 Bean 实例化的基础。框架和工具通常使用反射机制创建 Bean 实例,因此必须提供一个公共的无参构造器。

  • 属性 (Properties): 属性代表 Bean 的状态。访问和修改属性必须通过 getter 和 setter 方法,遵循严格的命名规范:getPropertyName() 和 setPropertyName(Type value)。

    • Boolean 属性: getter 方法可以是 isPropertyName() 或 getPropertyName()。

    • 索引属性: 用于访问数组或列表类型的属性,例如 getItem(int index) 和 setItem(int index, Type value)。

    • 绑定属性: 当属性值发生变化时,Bean 可以触发 PropertyChangeEvent。

    • 约束属性: 对属性值的修改可以被 veto。

  • 事件 (Events): Bean 可以触发事件并允许其他组件监听这些事件。这涉及到事件源、事件监听器和事件对象。

  • 内省 (Introspection): 框架和工具使用内省机制来发现 Bean 的属性、方法和事件。java.beans 包提供了用于内省的 API。BeanInfo 接口允许开发者显式地控制哪些信息暴露给外部。

  • 序列化 (Serialization): 实现 java.io.Serializable 接口使得 Bean 的状态可以被持久化到磁盘或通过网络传输。

2. Spring 与 Java Bean 的完美结合

Spring 框架的核心就是围绕 Java Bean 构建的。Spring 容器充当了 Bean 的工厂和管理器,负责创建、配置和组装 Bean。

Spring 利用 Java Bean 的优势:

  • 控制反转 (IoC): 对象之间的依赖关系由 Spring 容器管理,而不是由对象自身创建和维护。

  • 依赖注入 (DI): Spring 容器将依赖关系注入到 Bean 中,例如通过构造器注入、setter 注入或字段注入。

  • 面向切面编程 (AOP): Spring AOP 框架可以拦截 Bean 的方法调用,实现横切关注点的功能,例如日志记录、事务管理和安全控制。

3. Spring 中更丰富的 Bean 定义方式

除了 XML、注解和 Java 配置,Spring 还提供其他更灵活的 Bean 定义方式:

  • FactoryBean: FactoryBean 接口允许开发者自定义 Bean 的创建逻辑。

  • BeanDefinitionRegistryPostProcessor: 可以动态注册 Bean 定义。

  • BeanFactoryPostProcessor: 可以修改已注册的 Bean 定义。

4. 依赖注入的多种方式及细节

Spring 提供多种依赖注入方式:

  • 构造器注入: 通过构造器参数注入依赖。推荐使用这种方式,因为它可以确保 Bean 在创建时就拥有所有必要的依赖。

  • Setter 注入: 通过 setter 方法注入依赖。

  • 字段注入: 直接注入到字段上,使用 @Autowired 注解。方便但不太推荐,因为它绕过了 Bean 的构造函数,可能导致循环依赖等问题。

  • 方法注入: 通过方法参数注入依赖。

@Autowired 的细节:

  • required 属性: 默认为 true,表示必须找到匹配的 Bean,否则抛出异常。可以设置为 false,表示依赖是可选的。

  • @Qualifier 注解: 当存在多个相同类型的 Bean 时,可以使用 @Qualifier 注解指定要注入的 Bean。

5. Bean 作用域的详细说明

  • singleton (默认): 每个 Spring 容器只有一个实例。

  • prototype: 每次请求都会创建一个新的实例。

  • request: 每个 HTTP 请求创建一个新的实例。

  • session: 每个 HTTP 会话创建一个新的实例。

  • application: 每个 ServletContext 创建一个新的实例。

  • websocket: 每个 WebSocket 会话创建一个新的实例。

6. Bean 生命周期详解

Spring 容器管理 Bean 的完整生命周期:

  • 实例化: 创建 Bean 实例。

  • 属性赋值: 设置 Bean 的属性值。

  • 初始化: 调用初始化方法,例如 @PostConstruct 注解的方法或 init-method 属性指定的方法。

  • 使用: Bean 可以被应用程序使用。

  • 销毁: 调用销毁方法,例如 @PreDestroy 注解的方法或 destroy-method 属性指定的方法。

7. Spring Boot 示例:构建 RESTful API

java 复制代码
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;


@SpringBootApplication
public class MyApplication {

    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}


@RestController
@RequestMapping("/users")
class UserController {

    private final UserService userService;

    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public User getUser(@PathVariable Long id) {
        return userService.getUserById(id);
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }
}



@Service
class UserService {


    public  User getUserById(Long id) {
        // 模拟数据库查询
        User user = new User();
        user.setId(id);
        user.setName("John Doe");

        return user;
    }


    public User createUser(User user) {

        //模拟保存数据库
        return user;
    }



}


class User {

    private Long id;
    private String name;



    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }


}

这个示例演示了如何使用 Spring Boot 构建一个简单的 RESTful API,展示了依赖注入、Bean 的定义和使用等核心概念。

相关教程:

控制反转与依赖注入

感谢各位看官的观看,下期见,谢谢~

相关推荐
Abladol-aj15 分钟前
并发和并行的基础知识
java·linux·windows
清水白石00815 分钟前
从一个“支付状态不一致“的bug,看大型分布式系统的“隐藏杀机“
java·数据库·bug
Elihuss1 小时前
ONVIF协议操作摄像头方法
开发语言·php
Swift社区5 小时前
在 Swift 中实现字符串分割问题:以字典中的单词构造句子
开发语言·ios·swift
没头脑的ht5 小时前
Swift内存访问冲突
开发语言·ios·swift
没头脑的ht5 小时前
Swift闭包的本质
开发语言·ios·swift
wjs20245 小时前
Swift 数组
开发语言
吾日三省吾码6 小时前
JVM 性能调优
java
stm 学习ing6 小时前
FPGA 第十讲 避免latch的产生
c语言·开发语言·单片机·嵌入式硬件·fpga开发·fpga
Estar.Lee6 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi