【书籍阅读】【Spring实战】二 装配Bean
Spring配置的可选方案
①自动化装配Bean:@Component
②Java代码装配Bean:@Bean
③XML装配Bean
自动化装配Bean
Spring从两个角度实现对 @Component组件 的自动化装配:
①组件扫描:Xml或者JavaConfig配置
②自动装配:@AutoWire
创建可以被发现的Bean
创建一个CompactDisc接口 CompactDisc.java
public interface CompactDisc { void play(); }
创建CompactDisc的接口实现类
@Component public class BeautifulWorld implements CompactDisc{ private String title = "BeautifulWorld"; private String artist = "Hikaru"; @Override public void play() { System.out.println("Playing " + title + " by " + artist); } }
@Component组件注解标识其能够加入SpringIOC容器
开启组件扫描 使IOC能够检测到Bean
①通过xml开启:
<context:component-scan base-package="hikaru"/>
测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring.xml") public class CompactDiscTest { @Autowired private CompactDisc compactDisc; @Test public void play() { compactDisc.play(); } }
@RunWith标识让测试处于SpringTest测试环境下,否则不能够使用IOC容器中的Bean
@ContextConfiguration:location 则是加载Spring配置文件
②通过Java @ComponentScan开启:
ComponentScan参数默认有两种设置方式:
第一种是通过value,并且value可以省略,也可以替换为basePackages但是这种直接写String值的方式不安全
@Configuration @ComponentScan(value = {"hikaru.entity"}) public class JavaConfig { }
第二种是basePackageClasses
@Configuration @ComponentScan(basePackageClasses = CompactDisc.class) public class JavaConfig { }
测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = JavaConfig.class) public class CompactDiscTest { @Autowired private CompactDisc compactDisc; @Test public void play() { compactDisc.play(); } }
@ContextConfiguration classes表明使用的Spring配置文件
结果:
Playing BeautifulWorld by Hikaru
@AutoWire自动装配
上面测试中就使用了AutoWire自动装配,除此外自动装配也可以用于构造器和方法,Spring会自动对其参数添加@AutoWire注解。
为组件扫描的Bean命名
Spring会自动为Bean设置ID,默认值为类名的第一个字母小写,可以通过@Component(value = "id")进行修改。
如下有两种Bean注入了IOC:
@Component("BW") public class BeautifulWorld implements CompactDisc{ private String title = "BeautifulWorld"; private String artist = "Hikaru"; @Override public void play() { System.out.println("Playing " + title + " by " + artist); } }
@Component("CTY") public class CloseToYou implements CompactDisc{ private String title = "CloseToYou"; private String artist = "Hikaru"; @Override public void play() { System.out.println("Playing " + title + " by " + artist); } }
这时出现了Bean不唯一的情况导致装配失败:
通过@Qualifier选择指定ID的Bean
@Autowired @Qualifier("BW") private CompactDisc compactDisc;
如此便装配成功了
通过Java代码装配Bean
移除掉@ComponentScan注解扫描,在JavaConfig文件中直接通过@Bean注解告诉Spring该方法返回的对象要注册成为应用上下文中的Bean。
@Configuration //@ComponentScan(basePackageClasses = {CompactDisc.class}) public class JavaConfig { @Bean public CompactDisc BeautifulWorld() { return new BeautifulWorld(); } }
测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = JavaConfig.class) public class CompactDiscTest { @Autowired CompactDisc compactDisc; @Test public void test() { compactDisc.play(); } }
看起来每次自动装配的时候都调用了BeautifulWorld,但是实际上Spring会拦截BeautifulWorld方法的调用,然后返回第一次调用得到的Bean,因此每次装配得到的Bean都是同一个Bean,即Bean是单例的
通过XML装配Bean
略
导入和混合配置
在JavaConfig中引用XML配置
@Import(xxxxconfig.class) :引用其他的JavaConfig
@ImportResource("classpath:xxxx.xml"):引用xml配置
@Configuration @ImportResource("classpath:spring.xml") //@ComponentScan(basePackageClasses = {CompactDisc.class}) public class JavaConfig { }
测试:
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(classes = JavaConfig.class) public class CompactDiscTest { @Autowired CompactDisc compactDisc; @Test public void test() { compactDisc.play(); } }
JavaConfig并没有开启注解扫描,但是测试能够通过
在XML中引用JavaConfig配置
<bean class="hikaru.config.JavaConfig"> :在XML中引用JavaConfig配置
<import resource="classpath:spring.xml"/> :在xml中引入其他xml配置
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步