如何用Spring Java配置替代XML的三种autowire自动装配方式?
将Spring XML自动装配配置转为Java注解配置
要把XML中定义的三个AutowiredTargetBean实例(分别使用byName、byType、constructor自动装配,且均开启延迟初始化)转为Java注解配置,可按以下步骤实现:
1. 定义目标类与依赖类
首先准备AutowiredTargetBean类,对应三种装配方式设置不同的注入点;同时定义所需的依赖Bean:
依赖Bean定义
// 标记为@Primary,确保byType装配时能匹配到唯一的父类实例 @Component @Primary public class SomeDependency { // 示例业务逻辑 } // 命名为"namedDependency",用于byName装配匹配属性名 @Component("namedDependency") public class NamedDependency extends SomeDependency { // 示例子类业务逻辑 }
目标Bean类定义
public class AutowiredTargetBean { // 对应byName装配的属性(名称与上面的namedDependency Bean一致) private SomeDependency namedDependency; // 对应byType装配的属性 private SomeDependency typeDependency; // 对应constructor装配的属性 private SomeDependency constructorDependency; // 无参构造方法,用于byName/byType装配 public AutowiredTargetBean() {} // constructor装配用的构造方法 public AutowiredTargetBean(SomeDependency constructorDependency) { this.constructorDependency = constructorDependency; } // byName装配用的setter,@Autowired会自动匹配属性名对应的Bean @Autowired public void setNamedDependency(SomeDependency namedDependency) { this.namedDependency = namedDependency; } // byType装配用的setter,@Autowired按类型匹配唯一实例 @Autowired public void setTypeDependency(SomeDependency typeDependency) { this.typeDependency = typeDependency; } // 用于验证的getter方法 public SomeDependency getNamedDependency() { return namedDependency; } public SomeDependency getTypeDependency() { return typeDependency; } public SomeDependency getConstructorDependency() { return constructorDependency; } }
2. 核心配置类
使用@Configuration标记配置类,通过@Bean定义三个目标Bean实例,分别对应三种装配方式,并添加@Lazy实现延迟初始化:
@Configuration // 扫描依赖Bean所在的包路径,替换为你的实际包名 @ComponentScan(basePackages = "com.your.package") public class AutowireConfig { // 对应XML中的autowire="byName" + lazy-init="true" @Bean(name = "autowireByName") @Lazy public AutowiredTargetBean autowireByName() { return new AutowiredTargetBean(); // Spring会自动通过setter按属性名匹配namedDependency Bean } // 对应XML中的autowire="byType" + lazy-init="true" @Bean(name = "autowireByType") @Lazy public AutowiredTargetBean autowireByType() { return new AutowiredTargetBean(); // Spring会自动通过setter按类型匹配@Primary标记的SomeDependency Bean } // 对应XML中的autowire="constructor" + lazy-init="true" @Bean(name = "autowireByConstructor") @Lazy public AutowiredTargetBean autowireByConstructor(SomeDependency constructorDependency) { // 构造方法参数直接注入依赖,Spring自动按类型匹配 return new AutowiredTargetBean(constructorDependency); } }
3. 关键注解说明
@Configuration:标记类为Spring配置类,替代XML配置文件@Bean:定义单个Bean实例,name属性对应XML中的id@Lazy:对应XML中的lazy-init="true",标记Bean在首次被获取时才初始化@Autowired:实现自动装配,默认按类型匹配;当属性名与Bean名称一致时,自动触发byName匹配逻辑@Primary:当同类型存在多个Bean时,标记优先被byType装配的实例@ComponentScan:扫描指定包下的@Component标记类,自动注册为Spring Bean
4. 验证延迟初始化与装配结果
编写测试类验证效果,延迟初始化会在首次获取Bean时才触发初始化:
public class AutowireTest { public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(AutowireConfig.class); System.out.println("ApplicationContext 已初始化,但目标Bean未触发初始化"); // 获取byName Bean,触发初始化 AutowiredTargetBean byNameBean = context.getBean("autowireByName", AutowiredTargetBean.class); System.out.println("byName装配的依赖类型:" + byNameBean.getNamedDependency().getClass().getSimpleName()); // 获取byType Bean,触发初始化 AutowiredTargetBean byTypeBean = context.getBean("autowireByType", AutowiredTargetBean.class); System.out.println("byType装配的依赖类型:" + byTypeBean.getTypeDependency().getClass().getSimpleName()); // 获取constructor Bean,触发初始化 AutowiredTargetBean constructorBean = context.getBean("autowireByConstructor", AutowiredTargetBean.class); System.out.println("constructor装配的依赖类型:" + constructorBean.getConstructorDependency().getClass().getSimpleName()); } }
输出结果会显示:
- byName装配的是
NamedDependency(匹配属性名) - byType装配的是
SomeDependency(匹配@Primary的父类实例) - constructor装配的是
SomeDependency(按类型匹配) - 目标Bean均在首次获取时才完成初始化
内容的提问来源于stack exchange,提问作者Vladislav Miltsyn
相关产品推荐
相关产品推荐

