墨风如雪博客

  • 源码小店
  • 导航站
  • 登录
  • java
  • 资源分享
让AI使用变得如此简单
  1. 首页
  2. java
  3. spring
  4. 正文

spring 三大特性 IOC的详细指南

2023年 6月 1日 138点热度 0人点赞 0条评论

一、什么是IOC(Inversion of Control)(控制反转)?

  1. 传统编程模式的不足

在传统的编程模式中,程序员需要手动创建和管理对象之间的依赖关系,这会导致代码的耦合性和复杂性增加,同时也不利于代码的可维护性和可测试性。

  1. IOC的概念和作用

IOC是一种编程思想,它将对象的创建和依赖关系的管理交给IOC容器来完成。IOC容器是一个负责管理对象的容器,它会根据配置文件或注解来创建和管理对象之间的依赖关系,从而实现程序的松耦合和可维护性。

  1. IOC和DI(Dependency Injection)(依赖注入)的关系

DI是IOC的一种实现方式,它通过将对象的依赖关系注入到对象中来实现IOC。在DI中,IOC容器会根据配置文件或注解来创建对象,并将对象的依赖关系注入到对象中,从而实现对象之间的解耦和松散耦合。

二、Spring IOC的实现原理

2.1 BeanFactory和ApplicationContext的区别

BeanFactory是Spring IOC容器的基础接口,它提供了最基本的IOC功能,包括对象的创建和管理、依赖关系的维护、对象的生命周期等。但是,BeanFactory的性能较低,不适合在大规模应用中使用。

ApplicationContext是BeanFactory的子接口,它提供了更多的IOC功能,包括国际化、事件传播、AOP(面向切面编程)等。同时,ApplicationContext还支持多种配置方式,包括XML、注解和Java配置等。ApplicationContext的性能较好,适合在大规模应用中使用。

2.2 Bean的生命周期

Bean的生命周期包括初始化和销毁两个阶段。在Bean的初始化阶段,IOC容器会调用Bean的构造方法创建对象,并调用Bean的初始化方法进行对象的初始化。在Bean的销毁阶段,IOC容器会调用Bean的销毁方法进行对象的清理和释放资源。

Bean的生命周期可以通过实现InitializingBean和DisposableBean接口,或者使用@PostConstruct和@PreDestroy注解来实现。

例如:

public class User {
    private String name;
    private int age;

    public User() {
        System.out.println("User Constructor");
    }

    public void init() {
        System.out.println("User init");
    }

    public void destroy() {
        System.out.println("User destroy");
    }

    // getter and setter methods
}

在上面的例子中,User类实现了初始化和销毁方法init和destroy,这些方法会在IOC容器创建和销毁对象时被调用。

2.3 Bean的作用域

Bean的作用域决定了对象的生命周期和可见范围。在Spring中,Bean的作用域包括单例、多例、原型、会话和请求等。

  • 单例(Singleton):在整个IOC容器中只存在一个Bean实例,所有请求都返回同一个实例。
  • 多例(Prototype):每次请求都会创建一个新的Bean实例。
  • 原型(Singleton with prototype-bean):在整个IOC容器中只存在一个Bean实例,但是每次请求都会返回一个新的Bean实例。
  • 会话(Session):在Web应用中,每个用户会话都会创建一个新的Bean实例。
  • 请求(Request):在Web应用中,每个请求都会创建一个新的Bean实例。

Bean的作用域可以通过在配置文件或注解中指定来实现。

例如:

@Scope("prototype")
public class User {
    // fields and methods
}

在上面的例子中,User类的作用域被指定为多例(Prototype),每次请求都会创建一个新的User实例。

2.4 Bean的延迟加载

Bean的延迟加载是指在IOC容器初始化时不立即创建对象,而是在需要时才进行创建。延迟加载可以减少应用启动时间和内存占用,提高应用的性能。

延迟加载可以通过在配置文件或注解中指定来实现。

例如:

@Configuration
public class AppConfig {
    @Bean("user")
    @Lazy
    public User getUser() {
        return new User();
    }

在上面的例子中,使用@Lazy注解指定User Bean的延迟加载,只有在需要时才会进行创建。

2.5 Bean的自动装配

Bean的自动装配是指IOC容器自动将对象的依赖关系注入到对象中,省去了手动创建和管理对象之间的依赖关系的过程。Spring支持三种自动装配方式:按名称装配、按类型装配和构造方法装配。

  • 按名称装配:IOC容器会根据对象的属性名称自动匹配对应的Bean实例。
  • 按类型装配:IOC容器会根据对象的属性类型自动匹配对应的Bean实例。
  • 构造方法装配:IOC容器会根据对象的构造方法参数类型自动匹配对应的Bean实例。

自动装配可以通过在配置文件或注解中指定来实现。

例如:

public class User {
    @Autowired
    private UserDao userDao;
    // getter and setter methods
}

@Repository
public class UserDaoImpl implements UserDao {
    // methods
}

在上面的例子中,使用@Autowired注解自动装配User对象的userDao属性,IOC容器会自动匹配对应的UserDaoImpl实例。

三、Spring IOC的配置方式

3.1 基于XML的配置方式

基于XML的配置方式是Spring IOC最常见的配置方式,它通过XML文件来配置Bean的定义和依赖关系。在配置文件中,需要定义Bean的ID、类名、属性和依赖关系等信息。

例如:

<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="userDao" class="com.example.dao.UserDaoImpl"/>
    <bean id="userService" class="com.example.service.UserServiceImpl">
        <property name="userDao" ref="userDao"/>
    </bean>
</beans>

在上面的例子中,定义了两个Bean:userDao和userService,其中userService依赖于userDao。

3.2 基于注解的配置方式

基于注解的配置方式是Spring IOC的另一种常见配置方式,它通过注解来定义Bean和依赖关系。

例如:


```java
@Repository
public class UserDaoImpl implements UserDao {
    // methods
}

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    // methods
}

在上面的例子中,使用@Repository注解定义了UserDaoImpl Bean,使用@Service注解定义了UserServiceImpl Bean,并使用@Autowired注解自动装配了UserDaoImpl实例。

3.3 基于Java配置的方式

基于Java配置的方式是Spring IOC的一种相对较新的配置方式,它通过Java代码来定义Bean和依赖关系。在Java配置类中,需要定义Bean的方法和依赖关系。

例如:

@Configuration
public class AppConfig {
    @Bean("userDao")
    public UserDao getUserDao() {
        return new UserDaoImpl();
    }

    @Bean("userService")
    public UserService getUserService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(getUserDao());
        return userService;
    }
}

在上面的例子中,定义了一个Java配置类AppConfig,其中定义了两个Bean:userDao和userService,并在userService的方法中手动注入了userDao。

四、Spring IOC中的注解

4.1 @Component及派生注解(@Service、@Repository、@Controller)

@Component及其派生注解(@Service、@Repository、@Controller)是Spring IOC中最常见的注解,它们用于定义Bean和依赖关系。

@Component注解用于标注一个普通的Bean组件,它通常作为其他注解的基础。

@Service注解用于标注一个服务层的Bean组件。

@Repository注解用于标注一个数据访问层的Bean组件。

@Controller注解用于标注一个控制器层的Bean组件。

例如:

@Component
public class User {
    // fields and methods
}

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;
    // methods
}

@Repository
public class UserDaoImpl implements UserDao {
    // methods
}

@Controller
public class UserController {
    @Autowired
private UserService userService;
    // methods
}

在上面的例子中,使用@Component注解标注了User Bean,使用@Service注解标注了UserServiceImpl Bean,使用@Repository注解标注了UserDaoImpl Bean,使用@Controller注解标注了UserController Bean,并使用@Autowired注解自动装配了UserService实例。

4.2 @Autowired注解

@Autowired注解用于自动装配Bean的依赖关系,它可以用于字段、方法、构造方法和参数上。

例如:

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    private UserDao userDao;

    @Autowired
    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Autowired
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void addUser(User user) {
        userDao.addUser(user);
    }
}

在上面的例子中,使用@Autowired注解自动装配了UserDao实例,同时还使用@Autowired注解标注了构造方法和方法参数。

4.3 @Qualifier注解

@Qualifier注解用于指定自动装配Bean的名称或ID,用于解决多个Bean实例的冲突问题。

例如:

@Service
public class UserServiceImpl implements UserService {
   @Autowired
    @Qualifier("userDaoImpl")
    private UserDao userDao;

    // methods
}

在上面的例子中,使用@Qualifier注解指定了userDao实例的名称为"userDaoImpl",用于解决多个UserDao实例的冲突问题。

4.4 @Value注解

@Value注解用于注入配置文件中的属性值或表达式。

例如:


@Service
public class UserServiceImpl implements UserService {
    @Value("${maxPageSize}")
    private int maxPageSize;

    // methods
}

在上面的例子中,使用@Value注解注入了配置文件中的属性值maxPageSize。

五、总结

本文主要介绍了Spring IOC的概念、实现原理、配置方式和常见注解,希望读者能够通过本文了解和掌握Spring IOC的基本知识和应用技巧。在实际应用中,读者可以根据需要选择合适的IOC容器和配置方式,以提高应用的性能和可维护性。

本作品采用 知识共享署名 4.0 国际许可协议 进行许可
标签: AOP core DI ioc java spring springboot 核心容器
最后更新:2023年 5月 23日

墨风如雪

一个热爱生活,热爱分享的程序员

打赏 点赞
< 上一篇
下一篇 >

文章评论

您需要 登录 之后才可以评论

墨风如雪

一个热爱生活,热爱分享的程序员

最新 热点 随机
最新 热点 随机
Sora触手可及!微软必应AI视频生成器,全民创作时代来临? 阿里WebAgent开源:引领自主搜索新纪元 重磅炸弹!字节跳动开源BAGEL:70亿参数,统一多模态理解与生成,AI“全能王”诞生记! 小米MiMo-VL:7B参数,怎么就成了多模态界的“越级打怪王”? 炸裂!DeepSeek 8B 量化版降临:告别显存焦虑,你的 3080 Ti 也能玩转顶级大模型了! 美团炸场AI圈:点外卖点出个软件?用「对话式编程」重塑生产力!
炸裂!微软这门免费AI Agent新手课,GitHub近2万星,简直是宝藏!ComfyUI“打通任督二脉”:直接调用Veo2、GPT-4o等65大模型!一键串联你的AI工作流AI圈炸锅了!Mistral Medium 3:性能 SOTA,成本打骨折,企业玩家的新宠?字节终于开源“扣子”同款引擎了!FlowGram:AI 时代的可视化工作流利器告别“微信黑箱”!Chatlog:让你的聊天记录也能拥有“AI大脑”!字节跳动 Seed-Coder-8B:不靠人工洗数据,这80亿参数的小模型如何写出顶尖代码?
Git 基础概念和命令详解 USDT解析:探究这种数字货币的基本概念和作用 每日一道算法题:回文数算法详解 Suna 来了!这个能对话、能干活的开源 AI 智能体,也许是 Manus 的劲敌! 免费+性能双杀!百度文心大模型4.5/X1提前上线,开启AI普惠新时代 设计模式:命令设计模式
标签聚合
动态规划 算法 deepseek 教程 AI java spring 设计模式

COPYRIGHT © 2023 墨风如雪博客. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

免责声明 - 隐私政策