通过Java代码装配bean

本文介绍了在Spring中,当自动化配置不可行时如何通过Java代码进行bean的显式配置。这种方式提供了更强的灵活性,类型安全,并且方便重构。文章详细讲解了如何利用JavaConfig进行注解扫描以及显式创建bean实例,包括依赖注入和多配置类的组合使用。
摘要由CSDN通过智能技术生成

通过组件扫描和自动装配实现Spring的自动化配置是更为推荐的方式,但有时候自动化配置的方案行不通,因此需要明确配置Spring。

在进行显式配置时,通过Java代码装配bean是更好的方案,因为它更强大,类型安全并且重构。

JavaConfig是配置代码,意味着它不应包含任何业务逻辑,也不该侵入到业务逻辑代码中。通常将JavaConfig放到单独的包中,使它与其他的应用程序逻辑分离。

一、利用JavaConfig进行注解扫描(该部分只是用来替代XML中自动扫描,不是属于JavaConfig配置)
现在不是在XML文件中配置<\component-scan>。而是通过Java代码定义Spring的装配规则:

//启用组件扫描,默认会扫描与配置类相同的包及其子包(基础包),查找所有带@Component注解的类,
//但是将该配置文件单独放在一个包中,与其他应用代码区分开
@Configuration
//扫描一个包
@ComponentScan(basePackages = "org.springaction")
//扫描多个包
//@ComponentScan(basePackages = {"org.springaction","org.wdz.filter"})
//也可以指定包中包含的类或接口
//@ComponentScan(basePackageClasses = {CompactDisc.class, GuestFilter.class})
public class CDPlayConfig {
//不用写其他代码
}

测试一下:

@RunWith(SpringJUnit4ClassRunner.class)
//配置类
@ContextConfiguration(classes = CDPlayConfig.class)
public class CDPConfigTest {

    @Autowired
    private CompactDisc cd;

    @Test
    public void doP(){
        cd.play();
    }
}

二、显式产生bean实例
对上面的CDPlayConfig 进行修改,不再采用注解扫描,而是显式产生bean实例:

//将一个POJO标注为定义Bean的配置类
@Configuration
public class CDPlayConfig {
}

在类中编写方法,利用@Bean注解产生实例:

@Configuration
public class CDPlayConfig {
    //返回一个对象,注册为Spring应用上下文中的bean。
    //默认情况下,bean的ID与方法名是一样的。也可以设置一个不同的名字
    @Bean(name = "lonely")
    public CompactDisc sgtPeppers(){
        return new SgtPeppers();
    }
}

不使用默认无参的构造器构建实例,而是依赖一个bean。

//在同一个JavaConfig文件中

@Bean
    public CompactDisc cdPlay(){
        //构造器依赖一个CompactDisc。
        //因为sgtPeppers()添加了@Bean注解,Spring将会拦截所有对它的调用(它不是普通的方法),并确保直接返回该方法所创建的bean,而不是每次都对其进行实际的调用。
        return new CDPlat(sgtPeppers());
    }

//不是简单的调用sgtPeppers()的方法逻辑,而是从Spring容器中返回相应Bean的单例,不管调用多少次,都返回相同的Bean

@Bean
    public CompactDisc anthercdPlay(){
        //默认情况下,Spring中的bean都是单例的。
        //sgtPeppers()方法的调用返回的都是同一个bean。
       return new CDPlat(sgtPeppers());
    }

上面的Bean都是在同一个JavaConfig中定义的,如果Bean是在多个@Configuration中进行定义,也就是一个JavaConfig引用其他的JavaConfig。

//第一个JavaConfig配置
@Configuration
public class OneConfig{
  @Bean
  public CompactDisc sgtPeppers(){
     return new sgtPeppers();
   }
}

//由于@Configuration注解类本身已经标注了@Component注解,所以任何标注了@Configuration的类,本身也相当于标注了@Component,即它们可以像普通的Bean一样被注入其他的Bean中。

//第二个JavaConfig配置
@Configuration
public class TwoConfig{
  //像普通Bean一样注入CompactDisc  
    @Autowired
    private CompactDisc  compactDisc;

   @Bean
   public CDPlay cdPlay(){
   //像普通Bean一样,调用Bean相关的方法
      return new CDPlay(compactDisc.sgtPeppers());
    }
}

如果存在多个配置类,可以把它们组装到一个配置类中:

@Configuration
public class OneConfig{
  @Bean
  public CompactDisc  sgtPeppers(){
   return new sgtPeppers();
  }
}

//组装到另一个配置中(合二为一)

@Configuration
//使用Import注解
@Import(OneConfig.class)
public class ServiceConfig{
   @Bean
   public LoginServer loginServer(){
    return new LoginServer ();
   }

}

3、对于JavaConfig的配置,也可以使用ApplicationContext方式进行启动,获取相应的Bean:

public static void main(String[] args){
//构造函数的参数直接传入标注@Configuration的Java类
  ApplicationContext ctx=new AnnotationConfigApplicationContext(OneConfig.class);

  CompactDisc  sgtpeppees=ctx.getBean(CompactDisc.class);

}

如果需要注入多个@Configuration配置类,那么:

public static void main(String[] args){

  ApplicationContext ctx=new AnnotationConfigApplicationContext();
  //注册多个@Configuration配置类
  ctx.register(OneConfig.class);
  ctx.register(TwoConfig.class);

  //刷新容器以应用这些注册的配置类
  ctx.refresh();

   CompactDisc  sgtpeppees=ctx.getBean(CompactDisc.class);

}

可以对通过调用方法来引用bean的方式进行修改,更为常用的方式是:

//调用方法创建cdPlay bean的时候,会自动装配一个CompactDisc到配置的方法中
    //CompactDisc bean并不一定是在同一个配置类中引用@Bean方法产生的,它可以通过组件扫描或XML配置获得(不用管compactDisc是采用什么方式创建出来的)
    @Bean
    @Autowired
    public CompactDisc cdPlay(CompactDisc compactDisc){
        //在方法体中,可以按照合适的方式使用compactDisc bean,比如构造器和Setter方法
        CDPlat cdPlat=new CDPlat(compactDisc);
        cdPlat.setCompactDisc(compactDisc);
        return  cdPlat;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值