通过Java代码装配bean

来源:互联网 发布:java函数重载是指 编辑:程序博客网 时间:2024/06/08 02:29

通过组件扫描和自动装配实现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的配置类@Configurationpublic class CDPlayConfig {}

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

@Configurationpublic 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配置@Configurationpublic class OneConfig{  @Bean  public CompactDisc sgtPeppers(){     return new sgtPeppers();   }}//由于@Configuration注解类本身已经标注了@Component注解,所以任何标注了@Configuration的类,本身也相当于标注了@Component,即它们可以像普通的Bean一样被注入其他的Bean中。//第二个JavaConfig配置@Configurationpublic class TwoConfig{  //像普通Bean一样注入CompactDisc      @Autowired    private CompactDisc  compactDisc;   @Bean   public CDPlay cdPlay(){   //像普通Bean一样,调用Bean相关的方法      return new CDPlay(compactDisc.sgtPeppers());    }}

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

@Configurationpublic 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;    }
阅读全文
0 0