@Repository 注解便属于最先引入的一批,它用于将数据访问层 (DAO 层 ) 的类标识为 Spring Bean。
package bookstore.dao;
@Repository
public class UserDaoImpl implements UserDao{ …… }
// 其次,在 XML 配置文件中启动 Spring 的自动扫描功能
<beans … >
……
<context:component-scan base-package=”bookstore.dao” />
……
</beans>
在 XML 配置文件中启动 Spring 的自动扫描功能
<beans … >
……
<context:component-scan base-package=”bookstore.dao” />
…
</beans>
为什么 @Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为 Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类 型。
@Component 是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。 @Service 通常作用在业务层,但是目前该功能与 @Component 相同。 @Constroller 通常作用在控制层,但是目前该功能与 @Component 相同。
这三个注解除了作用于不同软件层次的类,其使用方式与 @Repository 是完全相同的。
当一个 Bean 被自动检测到时,会根据那个扫描器的 BeanNameGenerator 策略生成它的 bean 名称,会把 name 取值作为 Bean 的名字,这个注解不包含 name 值或是其他被自定 义过滤器发现的组件,默认 Bean 名称会是小写开头的非限定类名
如果你不想使用默认 bean 命名策略,可以提供一个自定义的命名策略
<beans ...>
<context:component-scan
base-package="a.b" name-generator="a.SimpleNameGenerator"/>
</beans>
与通过 XML 配置的 Spring Bean 一样,通过上述注解标识的 Bean,其默认作用域是"singleton",
在标注 Bean 的同时能够指定 Bean 的作用域,Spring 2.5 引入了 @Scope 注解。
@Scope("prototype")
@Repository
public class Demo { … }
如果你想提供一个自定义的作用域解析策略而不使用基于注解的方法,只需实现 ScopeMetadataResolver 接口,确认包含一个默认的没有参数的构造方法。然后在配置扫描器时提供全 限定类名:
<context:component-scan base-package="a.b"
scope-resolver="footmark.SimpleScopeResolver" />
4.使用 @PostConstruct 和 @PreDestroy 指定生命周期回调方法: Spring Bean 是受 Spring IoC 容器管理,由容器进行初始化和销毁的(prototype 类型由容器初始化之后便不受容器管理),通常我们不需要关注容器对 Bean 的初始化和销毁 操作,由 Spring 经过构造函数或者工厂方法创建的 Bean 就是已经初始化完成并立即可用的.
第一种方式:
是实现 Spring 提供的两个接口:InitializingBean 和 DisposableBean。
第二种方式是:
在 XML 文件中使用 的 init-method 和 destroy-method 属性指定初始化之后和销毁之前的回调方法,
第三种方式:
@PostConstruct 和 @PreDestroy。这两个注解使用非常简单,只需分别将他们标注于初始化之后执行的回调方法或者销毁之前执行的回调方法上。
由于使用了注解,因此需要配置相应的 Bean 后处理器,亦即在 XML 中增加如下一行:
<context:annotation-config />
使用 @Required 进行 Bean 的依赖检查: @Required 注解只能标注在 Setter 方法之上。因为依赖注入的本质是检查 Setter 方法是否被调用了,而不是真的去检查属性是否赋值了以及赋了什么样的值。如果将该注解标注 在非 setXxxx() 类型的方法则被忽略。 为了让 Spring 能够处理该注解,需要激活相应的 Bean 后处理器。要激活该后处理器,只需在 XML 中增加如下一行即可:
<context:annotation-config/>
当某个被标注了 @Required 的 Setter 方法没有被调用,则 Spring 在解析的时候会抛出异常,以提醒开发者对相应属性进行设置。
使用 @Resource、@Autowired 和 @Qualifier 指定 Bean 的自动装配策略:
no -- 显式指定不使用自动装配。
byName -- 如果存在一个和当前属性名字一致的 Bean,则使用该 Bean 进行注入。如果名称匹配但是类型不匹配,则抛出异常。如果没有匹配的类型,则什么也不做。
byType -- 如果存在一个和当前属性类型一致的 Bean ( 相同类型或者子类型 ),则使用该 Bean 进行注入。byType 能够识别工厂方法,即能够识别 factory-method 的返回类
型。如果存在多个类型一致的 Bean,则抛出异常。如果没有匹配的类型,则什么也不做。
constructor -- 与 byType 类似,只不过它是针对构造函数注入而言的。如果当前没有与构造函数的参数类型匹配的 Bean,则抛出异常。使用该种装配模式时,优先匹配参数最多的
构造函数。
autodetect -- 根据 Bean 的自省机制决定采用 byType 还是 constructor 进行自动装配。如果 Bean 提供了默认的构造函数,则采用 byType;否则采用 constructor 进
行自动装配。
使用 @Autowired 注解进行装配,只能是根据类型进行匹配。 当容器中存在多个 Bean 的类型与需要注入的相同时,注入将不能执行,我们可以给 @Autowired 增加一个候选值,做法是在 @Autowired 后面增加一个 @Qualifier 标注,提供一 个 String 类型的值作为候选的 Bean 的名字。
@Autowired(required=false)
@Qualifier("ppp")
public void setPerson(person p){}
@Qualifier 甚至可以作用于方法的参数 ( 对于方法只有一个参数的情况,我们可以将 @Qualifer 标注放置在方法声明上面,但是推荐放置在参数前面 ),
@Autowired(required=false)
public void sayHello(@Qualifier("ppp")Person p,String name){}
我们可以在配置文件中指定某个 Bean 的 qualifier 名字,方法如下:
<bean id="person" class="footmark.spring.Person">
<qualifier value="ppp"/>
</bean>
如果希望根据 name 执行自动装配,那么应该使用 JSR-250 提供的 @Resource 注解,而不应该使用 @Autowired 与 @Qualifier 的组合。@Resource 使用 byName 的方式 执行自动封装,如果 @Resource 没有指定 name 属性,那么使用 byName 匹配失败后,会退而使用 byType 继续匹配,如果再失败,则抛出异常。
使用 @Configuration 和 @Bean 进行 Bean 的声明:
Configuration 的类有如下要求: 配置类不能是 final 的; 配置类不能是本地化的,亦即不能将配置类定义在其他类的方法内部; 配置类必须有一个无参构造函数。
@Configuration
public class BookStoreDaoConfig{
@Bean
public UserDao userDao(){ return new UserDaoImpl();}
@Bean
public BookDao bookDao(){return new BookDaoImpl();}
}
Spring 在解析到以上文件时,将识别出标注 @Bean 的所有方法,执行之,并将方法的返回值 ( 这里是 UserDaoImpl 和 BookDaoImpl 对象 ) 注册到 IoC 容器中。默认情况 下,Bean 的名字即为方法名。因此,与以上配置等价的 XML 配置如下:
<bean id=”userDao” class=”bookstore.dao.UserDaoImpl”/>
<bean id=”bookDao” class=”bookstore.dao.BookDaoImpl”/>