在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 {@Autowiredprivate 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. 完整的运行流程
-
初始化Spring容器:在
AppConfig.main()方法中,我们通过AnnotationConfigApplicationContext来加载配置类AppConfig。 -
自动装配Bean:Spring容器扫描包路径,找到所有带有
@Component注解的类,并创建这些类的实例。 -
获取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中注入。
五、小结
-
使用Spring的注解配置方式可以大大简化配置,特别是通过
@Component和@Autowired注解来实现Bean的自动装配。 -
@ComponentScan注解帮助Spring容器自动扫描指定包中的Bean,并根据依赖关系进行注入。 -
配置类通常需要放在项目的顶层包中,其他Bean按照功能分类放置在子包内。
-
对于没有
@Component注解的第三方Bean,可以通过@Bean注解或手动配置来注册。
通过注解配置,Spring IoC容器的配置变得更加简洁高效,适合开发者在实际项目中快速构建与维护。
1837

被折叠的 条评论
为什么被折叠?



