@Configuration
@Configuration 注解是一个类级别的注解,也是 @Component 的衍生注解,它指示 Spring 容器该类是一个配置类并且应该被处理以生成 Bean 定义和服务请求。@Configuration 注解告诉 Spring 容器这个类是一个 Bean 配置文件,其中可能包含了多个 Bean 的定义。
通过 @Configuration 注解,我们就可以完全替换掉 XML 配置的方式。
需要注意的是,在原来的测试类中,创建 Spring 工厂使用的是 ClassPathXmlApplicationContext,当我们想要使用 @Configuration 配置 Bean 来创建工厂时,我们需要使用 AnnotationConfigApplicationContext。在使用这个类的时候,我们可以直接传入配置 Bean 的 Class,也可以指定一个包路径。
创建配置类
package world.xuewei.config; import org.springframework.context.annotation.Configuration; /** * Spring 配置 Bean * * @author 薛伟 * @since 2023/10/27 14:42 */ @Configuration public class AppConfig { }
创建测试类
package world.xuewei; import org.junit.Before; import org.junit.Test; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.AnnotationConfigApplicationContext; import world.xuewei.config.AppConfig; /** * 配置 Bean 测试 * * @author 薛伟 * @since 2023/10/26 10:17 */ public class ConfigurationTest { private ApplicationContext context; @Before public void before() { // 指定配置类的 Class,创建 Spring 工厂 context = new AnnotationConfigApplicationContext(AppConfig.class); // 指定配置类所在的包路径,配置 Bean 需要在此包或者子包下 context = new AnnotationConfigApplicationContext("world.xuewei"); } @Test public void test1() { } }
@Bean
在 Spring 框架中,@Bean 注解用于将方法标记为 Bean 定义提供程序。通过在 @Configuration 注解的类中使用 @Bean 注解,您可以告诉 Spring 容器该方法将返回一个对象,该对象应该被注册为 Spring 上下文中的 Bean。
@Bean 注解有以下特点和用途:
- 方法级别的注解:@Bean 注解是一个方法级别的注解,它通常用于 @Configuration 注解的类中的方法上。
- Bean 定义:当使用 @Bean 注解标记一个方法时,该方法的返回值将被注册为一个 Spring Bean。Spring 容器将根据方法返回的对象类型自动创建 Bean,并将其添加到应用程序上下文中。
- 自定义 Bean 名称:默认情况下,Bean 的名称与带有 @Bean 注解的方法名称相同。您可以通过在 @Bean 注解中指定 name 属性来自定义 Bean 的名称。
- 依赖注入:@Bean 注解还可以处理依赖注入。如果 @Bean 方法需要其他 Bean 作为参数,Spring 容器将自动解析并注入这些依赖项。
- 单例作用域:默认情况下,通过 @Bean 注解注册的 Bean 是单例的。这意味着每次从 Spring 容器获取该 Bean 时,都会返回同一个实例。可以搭配 @Scope 注解改变对象的作用域。
- 配置外部库:@Bean 注解非常适合用于配置第三方库或外部组件,您可以将其实例化并注册为 Spring Bean,以便在应用程序中使用。
注意:当 @Bean 标记在一个方法上的时候,这个方法必须是 public 的。返回值就是 Bean 的类型,方法名默认就是 Bean 的 id。如果有参数,那么参数会自动的注入。
示例 Demo
package world.xuewei.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.PropertySource; import org.springframework.context.annotation.Scope; import world.xuewei.dao.AccountDao; import world.xuewei.entity.Account; import world.xuewei.service.AccountService; import world.xuewei.service.AccountServiceImpl; import java.sql.Connection; import java.sql.DriverManager; /** * Spring 配置 Bean * * @author 薛伟 * @since 2023/10/27 14:42 */ @Configuration @PropertySource("classpath:db.properties") public class AppConfig { /** * 连接驱动 */ @Value("${jdbc.driveName}") private String driveName; /** * 连接地址 */ @Value("${jdbc.url}") private String url; /** * 用户名 */ @Value("${jdbc.username}") private String username; /** * 密码 */ @Value("${jdbc.password}") private String password; /** * 创建一个 id 为默认方法名 account 的 Bean */ @Bean public Account account() { return new Account(1, "xw", "123456"); } /** * 创建一个 id 为 acc 的 Bean,并且为多实例 */ @Bean(name = "acc") @Scope("prototype") public Account account1() { return new Account(1, "xw", "123456"); } /** * 创建复杂对象 Bean */ @Bean public Connection connection() { Connection connection = null; try { Class.forName(driveName); connection = DriverManager.getConnection(url, username, password); } catch (Exception e) { throw new RuntimeException(e); } return connection; } @Bean public AccountDao accountDao() { return new AccountDao(); } /** * 创建 AccountService Bean * * @param accountDao 自动注入 AccountDao */ @Bean public AccountService accountService(AccountDao accountDao) { AccountServiceImpl accountService = new AccountServiceImpl(); accountService.setAccountDao(accountDao); return accountService; } }
@ComponentScan
@ComponentScan
注解是 Spring 提供的一种基于注解的配置方式,它可以在 Java 类上直接使用,也可以在配置类上使用。
@ComponentScan
注解包含几个重要的属性:basePackages
、 excludeFilters
、 includeFilters
、 useDefaultFilters
。作用和上述 XML 方式一样。
@ComponentScan(basePackages = "world.xuewei", excludeFilters = { @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = Account.class), @ComponentScan.Filter(type = FilterType.ANNOTATION, value = Service.class), @ComponentScan.Filter(type = FilterType.REGEX, pattern = ".*Test"), @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "world.xuewei.dao..*"), @ComponentScan.Filter(type = FilterType.CUSTOM, classes = MyCustomFilter.class), }) @Component public class AnnotationTest { // ... }
具体配置内容可查看前面整理的《Spring注解扫描》
@Import
在 Spring 框架中,@Import 注解用于将其他配置类导入当前配置类中。通过使用 @Import 注解,您可以将其他配置类中的 Bean 定义引入到当前配置类中,从而实现 Bean 的组合和重用。
@Import 注解有以下特点和用途:
- 导入其他配置类:@Import 注解允许您将其他配置类导入到当前配置类中。这意味着您可以将其他配置类中定义的 Bean 引入到当前配置类中,并将其注册为 Spring 上下文中的 Bean。
- 组合和重用 Bean:通过 @Import 注解,您可以将多个配置类中定义的 Bean 组合在一起,以创建更复杂的应用程序上下文。这使得 Bean 的重用和组合变得更加容易。
- 多态性:@Import 注解支持多态性,这意味着您可以使用父类或接口类型来引用导入的 Bean。这使得应用程序更加灵活和易于扩展。
- 条件导入:@Import 注解还支持条件导入,这意味着您可以根据特定条件选择性地导入配置类。例如,您可以根据运行时环境的不同导入不同的配置类。
配置类的引入
@Configuration public class AppConfig1 { // 配置类1的内容 } @Configuration public class AppConfig2 { // 配置类2的内容 } @Configuration @Import({AppConfig1.class, AppConfig2.class}) public class MainConfig { // 主配置类的内容 }
普通类的引入
@Configuration @Import({UtilClass1.class, UtilClass2.class, ...}) public class AppConfig { // 配置类的内容 }
@Import
注解导入了多个普通类,这些类将被自动注册为 Spring 容器中的 Bean,可以在其他组件中进行依赖注入或使用。
@ImportResource
@ImportResource
注解是 Spring 框架中的一个注解,用于在配置类中引入 XML 配置文件。通过 @ImportResource
注解,我们可以将 XML 配置文件中定义的 bean 引入到当前的配置类中,从而实现 XML 配置文件与 Java 配置类的混合使用。
@Configuration @ImportResource("classpath:example.xml") public class AppConfig { // 配置类的内容 } @Configuration @ImportResource({"classpath:example1.xml", "classpath:example2.xml"}) public class AppConfig { // 配置类的内容 }
注意:
@ImportResource
注解只能用于@Configuration
注解标记的配置类中。