在博客中为了演示容器Bean实例化时暴露出的几个接口,将UserBean配置在XML中,其实常见的Bean的配置有3种。1.基于xml配置Bean 2.使用注解定义Bean 3.基于java类提供Bean定义信息。

一、基于xml配置Bean

基于XML配置Bean时,Spring通过<bean>配置来实例化、设置bean的属性以及设置bean间的相互依赖性。一个<bean>通常需要定义id和class属性。class属性是必须的,不然Spring怎么知道是哪个呢。id不是必须的,不过如果配置文件中配置的其他bean要引用该bean,则id也是必须的,通常都加上。

<bean id="user" class="com.demo.model.UserBean"></bean>

二、使用注解定义Bean

如果采用基于XML的配置,bean定义信息和bean实现类本身是分离的,而采用基于注解的配置方式时,bean定义信息即通过在bean实现类上标注注解实现。在第二章节中定义Air和Person时都使用了@Component来注解bean。

package com.demo.model;

import org.springframework.stereotype.Component;

@Component
public class CleanAir implements IAir {
    @Override
    public String toString() {
        
        return  "CleanAir";
    }
}

我们使用@Component注解在CleanAir 类声明处对类进行标注,它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的bean。它和<bean id="CleanAir" class="com.demo.model.CleanAir"></bean>是等效的。除了@Component以外,Spring提供了3个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:

@Repository:用于对DAO实现类进行标注;
@Service:用于对Service实现类进行标注;
@Controller:用于对Controller实现类进行标注;

那问题来了:既然都是bean,为什么还提供4个,因为这样让注解的用途更加清晰,而且不同的注解也有各自特殊的功能。

三、基于java类提供Bean定义

在普通的POJO类中只要标注@Configuration注解,就可以为spring容器提供bean定义的信息了,每个标注了@Bean的类方法都相当于提供了一个bean的定义信息。

package com.demo.model;

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

@Configuration
public class AppConf {
    
    @Bean
    public CleanAir cleanAir(){
       return new CleanAir();    
    }
    @Bean
    public DirtyAir dirtyAir(){
       return new DirtyAir();    
    }
    
    @Bean
    public Person person(){
        return new Person(dirtyAir());
    }
}

我们只需在xml中配置开启context扫描即可实现bean的配置。省去了配置Person、DirtyAir。

<context:component-scan base-package="com.demo.model"/>
  <bean id="conf" class="com.demo.model.AppConf"/>
       ApplicationContext context=new ClassPathXmlApplicationContext(new String[]{"ApplicationContext.xml"});
        BeanFactory factory=context;
        AppConf conf=(AppConf)factory.getBean("conf");
        conf.person().Breath();

输出结果:

DirtyAir

基于java类的配置方式和基于XML或基于注解的配置方式相比,前者通过代码的方式更加灵活地实现了Bean的实例化及Bean之间的装配,但后面两者都是通过配置声明的方式,在灵活性上要稍逊一些,但是配置上要更简单一些。