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',可以通过注解直接指定Bean的scope,例如:
@Scope("prototype")
@Component("helloService")
public class HelloServiceImpl implements HelloService {}Resource依赖配置
像上面例子中的private Hello hello;加上了@Resource注解,这样就可以将相应的Bean注入到该属性中。@Resource有一个name属性,用于指定需要被注入的Bean的实例的标识(id),也就是说,使用@Resource的name属性与<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容器中有多个同类型的Bean与Field类型匹配,则会出现异常。
- 当@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;
    }