Spring(三): 注解



Bean的注解

Spring提供了如下几个Annotation来标注Spring Bean:

  • @Component: 标注一个普通的Spring Bean
  • @Controller: 标注一个控制器组件类(控制层);
  • @Service: 标注一个业务逻辑组件类(业务层);
  • @Repository: 标注一个Dao组件(持久层);

然后在spring的配置文件中添加<context:component-scan base-package="" />,会自动搜索包下所有以@Component@Controller@Service@Repository注释的java类,当作Spring Bean处理。

注意 添加注解时如果不指定名字,则会默认生成一个与类同名但是第一个字母小写的名字, 如HelloServiceImpl会自动生成helloServiceImpl
当然可以自己指定名字,像下面这样:

@Component("helloService")
public class HelloServiceImpl implements HelloService{

    @Resource
    private Hello hello;

    // 如果有<bean>元素且使用了<property>子标签,setter必须有
    public void setHello(Hello hello) {
        this.hello = hello;
    }

    @Override
    public void testHello() {
        hello.sayHello();
    }
}

Scope作用域

@Scope用于指定一个Bean产生的方式,默认为’singleton’,可以通过注解直接指定Beanscope,例如:

@Scope("prototype")
@Component("helloService")
public class HelloServiceImpl implements HelloService {}

Resource依赖配置

像上面例子中的private Hello hello;加上了@Resource注解,这样就可以将相应的Bean注入到该属性中。
@Resource有一个name属性,用于指定需要被注入的Bean的实例的标识(id),也就是说,使用@Resourcename属性<property../>元素的ref属性具有相同的效果。

    @Resource(name = "hello")
    private Hello hello;
    //注解中的name作用与下面的ref作用相同
    <property name="属性名" ref="Bean的id"/>

使用@Resource可以标识属性、setter方法

  • 当使用@Resource修饰setter方法,若省略name属性,则name属性默认值是从该setter方法去掉set子串之后首字母小写的子串。
  • 当使用@Resource修饰Field时,若省略name,则默认与Field的相同。

Autowired自动装配

像上面的@Resource是通过byName方式(通过id)进行注入,而@Autowired是通过byType策略进行注入,所以若有多个同类型的Bean就容易出问题,为了避免这种问题,一般与Qualifier精装配联合使用。

使用@Autowired可以标识属性、setter方法、普通方法、构造器(例子见@Qualifier中)

注意:

  • @Autowired标注Field时,Spring会把容器中的与该Field类型匹配的Bean注入该属性,如果Spring容器中有多个同类型的BeanField类型匹配,则会出现异常。
  • @Autowired标注数组或集合类的属性时,Spring会自动搜索Spring容器中所有与数组类型相匹配的类型的Bean,并把这些Bean当作数组的元素来创建数组。

Qualifier精装配

为了避免自动装配的问题,实现精确的配置,Spring提供@Qualifier,可以根据Bean标识(id)来指定自动装配。

    // 标注属性
    @Autowired
    @Qualifier("hello")
    private Hello hello;

    // Autowired标注数组,则所有Hello类型的Bean都会放到数组里
    @Autowired
    private Hello[] hellos;

    // Autowired标注构造方法,Qualifier标注方法的形参
    @Autowired
    public HelloServiceImpl(@Qualifier("hello")Hello hello) {
        this.hello = hello;
    }