实战Spring通过Java代码装配bean

在很多场景下通过组件扫描和自动装配实现Spring的自动化配置是更为推荐的方式,但有时候自动化配置的方案行不通,也就是自定义的时候。

比如说,你想要将第三方库中的组件装配到你的应用中,在这种情况下,是没有办法在它的类上添加@Component和@Autowired注解的,因此就不能使用自动化装配的方案了。

目录

创建配置类

声明简单的bean

借助JavaConfig实现注入

小结


进行显式配置的时候,有两种可选方案:Java和XML。

显式配置时,JavaConfig是更好的方案,因为它更为强大、类型安全并且对重构起来更加方便。因为它本身就是Java代码,就像 应用程序中的其他Java代码一样。但是要单一职责,这个配置代码,不要与业务代码混淆,JavaConfig也不应该侵入到业务逻辑代码之中,尽可能将 配置代码,放到单独包中去,这样对于它的意图就不会产生困惑了。

创建配置类

@Configuration
public class CDPlayerConfig {
    ...
}

随便创建一个类,然后 添加@Configuration注解,@Configuration注解表明这个类是一个配置类。

与上一篇 配置类不同的是,CDPlayerConfig的@ComponentScan注解移除掉了。移除之后在进行测试,会抛异常为:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'soundsystem.CDPlayOneTest':
 Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: 
private soundsystem.CompactDisc soundsystem.CDPlayOneTest.cd; 
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type [soundsystem.CompactDisc] found for dependency: 
expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: 
{@org.springframework.beans.factory.annotation.Autowired(required=true)}

会报一些很长的错,看到最后是说 required 为 true,他默认值为 true,为了避免异常的出现,你可以将@Autowired的required属 性设置为false。但是这不是解决这个问题的方法。

这个问题就是说 Could not autowire field,注入失败,测试期望被注入CDPlayer和CompactDisc,但是这些bean根本就没有创建,因为组件扫描不会发现它们。这要是@ComponentScan注解的作用所在。

声明简单的bean

比方说,下面的代码声明了CompactDisc bean:

package soundsystem;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CDPlayerConfig {

    /**
     * compactDisc
     *
     * @param
     * @return soundsystem.CompactDisc
     * @author imenger
     * @date 2021/2/25 10:20 上午
     * @Bean注解会告诉Spring这个方法将会返回一个对象,该对象要注册为Spring应用上下文中的bean。
     */
    @Bean
    public CompactDisc compactDisc() {
        return new SgtPeppers();
    }

}

bean的ID与带有@Bean注解的方法名是一样的。在本例中,bean的名字将会是sgtPeppers。如果你想为其设置成一个不同的 名字的话,那么可以重命名该方法,也可以通过name属性指定一个不同的名字:

 @Bean(name = "vcd")

@Bean注解到底是做啥的?

借助JavaConfig实现注入

我们需要 声明CDPlayer这个bean,它依赖于CompactDisc。在JavaConfig中,要如何将它们装配在一起呢?

在JavaConfig中装配bean的最简单方式就是引用创建bean的方法。例如,下面就是一种声明CDPlayer的可行方案:

 @Bean
    public CDPlayer cdPlayer() {
        return new CDPlayer(compactDisc());
    }

同样使用了@Bean注解,所以,调用 compactDisc() 方法也就创建了一个  CompactDisc 类,最终创建 CDPlayer 类。这表明这个方法会创建一个bean实例并将其注册到Spring应用上下 文中。所创建的bean ID为cdPlayer,与方法的名字相同。

以上调用有点循环嵌套,看上去有点繁琐,其是可以直接传参调用。

 @Bean
    public CDPlayer cdPlayer(CompactDisc compactDisc) {
        return new CDPlayer(compactDisc);
    }

通过这种方式引用其他的bean通常是最佳的选择,因为可以直接将 CompactDisc 类注入进来,不用 在调用 compactDisc() 这个方法。

小结

其是这个 @Bean 注解,不仅仅可以用在声明 类的方法上,或者 单独的 setter 方法上,只要你想用,在满足你的需求上 哪里都能用。

这个配置就等同于之前在xml里的配置,下篇文章会写到 xml 的配置,xml 的配置大家应该用的 比较多点,也是很多人都认可的配置方式。

<beans>
    <bean id="transferService" class="com.acme.TransferServiceImpl"/>
</beans>
 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值