Spring中Bean的定义及作用域的注解实现

2014-12-14 17:05

Classpath扫描与组件管理:

从Spring3.0开始,Spring JavaConfig项目提供了很多特性,包括使用java而不是xml定义bean,指的是注解

@Configuration,@Bean ,@Import ,@DependsOn

@Component是一个通用注解,可用于任何bean

@Repository:通常用于注解DAO类,即持久层

@Service:通常用于注解Service类,即服务层

@Controller:通常用于Controller类,即控制层MVC

元注解(Meta-annotations)

元注解即注解的注解,许多Spring提供的注解可以作为自己的代码,即"元数据注解",元注解是一个简单的注解,可以应用到另一个注解

下列定义Service注解时,用@Component注解来修饰,@Service拥有@component注解的功能:

@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component  // Spring will see this and treat @Service in the same way as @Component
public @interface Service {
    // ....
}

我们也可以自己定义注解.

类的自动检测及Bean的注册

Spring可以自动检测类并注册Bean到ApplicationContext中.

例:@Service,@Component,@Repository要注册到类上(类的注解),还有注册在方法上的注解像@Autowired,这些注解可以被自动检测到的

注册在类上的,则可以作为Bean自动注册到ApplicationContext中去

为了能够检测这些类并注册相应的Bean,需要在xml文件中配置下面内容:

<context:component-scan base-package="org.example" />

自动扫描org.example包下面的类

<context:component-scan>包含<context:annotation-config>,通常在使用前者后,就不再使用后者.因为使用前者后,已经包含后者的全部功能.通常使用前者

使用过滤器进行自定义扫描

默认情况下,类被自动发现并注册bean的条件是:使用@Component,@Repository,@Service,@Controller注解或者使用@Component注解的自定义注解

可以通过过滤器修改上面的行为.

如:忽略所有的@Repository注解并用"Stub"代替

<beans>
    <context:component-scan base-package="org.example">  
        <context:include-filter type="regex" expression=".*Stub.*Repository" />
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository" />
    </context:component-scan>
</beans>

type类型:annotation基于注解,assignable基于类或接口,aspectj基于aspectj,regex基于正则表达式,custom基于自定义

还可使用use-default-filters="false"禁用自动发现与注册

定义Bean

扫描过程中组件被自动检测,那么Bean名称是由BeanNameGenerator生成的(@Component,@Repository,@Service,@Controller都会有个name属性用于显示设置Bean Name)

@Service("myMovieLister")
public class SimpleMovieLister {
    // ....
}

也可以自己生成Bean名称,Bean名称为类名的第一个字母小写.

也可以自定义bean命名策略,实现BeanNameGenetator接口,并一定要包含一个无参数构造器

<beans>
    <context:component-scan base-package="org.example" name-generator="org.example.MyNameGenerator" />
</beans>

name-generator="org.example.MyNameGenerator"
指定命名规则的实现

作用域

可用注解@Scope来指明作用域

也可以自定义scope策略,实现ScopeMetadataResolver接口并提供一个无参构造器

<beans>
    <context:component-scan base-package="org.example" scope-resolver="org.example.MyNameGenerator" />
</beans>

代理方式

可以使用scoped-proxy属性指定代理,有三个值可选:no,interfaces,targetClass

<beans>
    <context:component-scan base-package="org.example" scoped-proxy="interfaces" />
</beans>