【Java教程】Day22-05 Spring框架:IoC容器——使用Spring的IoC容器

在Spring框架中,IoC(控制反转)容器的核心作用是根据预定义的配置(如XML或注解)管理Bean的生命周期和依赖关系。我们通过配置文件描述Bean的依赖关系,Spring容器将自动创建并装配Bean。一旦容器初始化完成,我们就可以直接从容器中获取Bean并使用它们。

一、使用XML配置的优缺点

使用XML配置的方式,我们将所有的Bean配置放在一个或多个XML文件中。其主要优点是所有的Bean及其依赖关系都能一目了然,且通过配置注入的方式,依赖关系显得非常直观。然而,这种方式也有一些缺点:每增加一个组件,就必须手动修改XML文件,尤其是在系统庞大时,配置的复杂度和维护成本会急剧上升。

二、 有没有更简洁的配置方式?

当然有!Spring 通过 注解配置 方式,允许开发者避免繁琐的XML配置,能够更简便地进行Bean的注入与装配。下面我们将展示如何通过注解来配置Spring IoC容器。

三、使用注解配置Spring IoC容器

1. 配置MailService类

首先,我们在 MailService 类上添加 @Component 注解,表示该类是一个Bean,Spring将会自动管理它的实例。


 

 

java@Componentpublic class MailService {    private ZoneId zoneId = ZoneId.systemDefault();    public void setZoneId(ZoneId zoneId) {        this.zoneId = zoneId;    }    public String getTime() {        return ZonedDateTime.now(this.zoneId).format(DateTimeFormatter.ISO_ZONED_DATE_TIME);    }    public void sendLoginMail(User user) {        System.out.println(String.format("Hi, %s! You are logged in at %s", user.getName(), getTime()));    }    public void sendRegistrationMail(User user) {        System.out.println(String.format("Welcome, %s!", user.getName()));    }}

 

通过 @Component 注解,Spring将自动创建该类的实例,并注册为一个Bean。默认情况下,Spring会将Bean的名称设置为类名的首字母小写形式, 即 mailService

2. 配置UserService类

接下来,在 UserService 类中,我们同样使用 @Component 注解标记该类为一个Spring管理的Bean,同时使用 @Autowired 注解自动注入 MailService 实例。


 
java@Componentpublic class UserService {    @Autowired    private MailService mailService;    private List<User> users = new ArrayList<>(List.of(        new User(1, "bob@example.com", "password", "Bob"),        new User(2, "alice@example.com", "password", "Alice"),        new User(3, "tom@example.com", "password", "Tom")    ));    public User login(String email, String password) {        for (User user : users) {            if (user.getEmail().equalsIgnoreCase(email) && user.getPassword().equals(password)) {                mailService.sendLoginMail(user);                return user;            }        }        throw new RuntimeException("login failed.");    }    public User getUser(long id) {        return this.users.stream().filter(user -> user.getId() == id).findFirst().orElseThrow();    }    public User register(String email, String password, String name) {        users.forEach(user -> {            if (user.getEmail().equalsIgnoreCase(email)) {                throw new RuntimeException("email exist.");            }        });        User user = new User(users.stream().mapToLong(u -> u.getId()).max().getAsLong() + 1, email, password, name);        users.add(user);        mailService.sendRegistrationMail(user);        return user;    }}

 

@Autowired 注解表示自动注入 MailService,Spring容器会根据类型自动装配这个Bean。我们可以将 @Autowired 注解放在字段、构造函数或setter方法上。通常,我们会将其放在字段上,避免额外的setter方法。

3. 创建配置类AppConfig

为了让Spring能够识别并扫描这些注解,我们需要创建一个配置类,并通过 @Configuration 注解标明它是一个配置类。同时,使用 @ComponentScan 注解指定扫描的包路径。


 
java@Configuration@ComponentScanpublic class AppConfig {    public static void main(String[] args) {        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);        UserService userService = context.getBean(UserService.class);        User user = userService.login("bob@example.com", "password");        System.out.println(user.getName());    }}

 

在这个配置类中,@ComponentScan 注解告诉Spring容器扫描当前包及其子包下所有标有 @Component 注解的类,并自动注册为Bean。AnnotationConfigApplicationContext 是Spring 通过注解进行配置时使用的容器实现类。

4. 项目目录结构


 

 

plaintextspring-ioc-annoconfig├── pom.xml└── src    └── main        └── java            └── com                └── itranswarp                    └── learnjava                        ├── AppConfig.java                        └── service                            ├── MailService.java                            ├── User.java                            └── UserService.java

 

5. 完整的运行流程

  1. 初始化Spring容器:在 AppConfig.main() 方法中,我们通过 AnnotationConfigApplicationContext 来加载配置类 AppConfig

  2. 自动装配Bean:Spring容器扫描包路径,找到所有带有 @Component 注解的类,并创建这些类的实例。

  3. 获取Bean并使用:通过 context.getBean(UserService.class) 获取已经由Spring装配的 UserService 实例,进而可以调用其方法来进行登录或注册操作。

6. 配置Bean的注意事项

  • 包结构设计:使用 @ComponentScan 时,务必保证配置类 AppConfig 在项目的顶层包下,其他Bean根据功能放置在子包中。这样,Spring才能正确扫描并装配它们。

  • 第三方Bean注入:如果你想注入一个第三方的Bean(如 HikariDataSource),而该Bean没有 @Component 注解,可以通过手动配置的方法来将其加入容器,或者通过 @Bean 注解注册到配置类中。

四、 思考题:如何注入第三方Bean?

如果我们想注入一个没有 @Component 注解的Bean(如 HikariDataSource),可以通过以下方式解决:


 
java@Beanpublic DataSource dataSource() {    HikariDataSource dataSource = new HikariDataSource();    dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/test");    return dataSource;}

 

通过 @Bean 注解,Spring会把这个方法返回的对象注册为一个Bean,并可以在其他Bean中注入。

五、小结

  1. 使用Spring的注解配置方式可以大大简化配置,特别是通过 @Component 和 @Autowired 注解来实现Bean的自动装配。

  2. @ComponentScan 注解帮助Spring容器自动扫描指定包中的Bean,并根据依赖关系进行注入。

  3. 配置类通常需要放在项目的顶层包中,其他Bean按照功能分类放置在子包内。

  4. 对于没有 @Component 注解的第三方Bean,可以通过 @Bean 注解或手动配置来注册。

 

通过注解配置,Spring IoC容器的配置变得更加简洁高效,适合开发者在实际项目中快速构建与维护。

 

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值