您的位置:首页 > 编程语言 > Java开发

【Java.Spring.Core】【IoC】使用Classpath扫描向容器注册beans/components

2015-01-11 23:59 537 查看
在上一小节中,演示了如何使用代码层次上的注解来配置元数据。但是,大量的基础bean还是显式的定义在XML文件中,注解只是用来完成依赖注入。

该小节提供了一种选择,通过扫描 classpath 隐式地检测 candidate components。candidate components是匹配过滤策略,拥有bean定义的类。这可以不必使用XML文件来实现bean的注册,而是使用注解,AspectJ 类型表达式,或者自定义的filter criteria来选择哪些类将会被注册到bean 容器中。

further stereotype注解 (@Component, @Service, @Controller, @Repository)

Spring提供了further stereotype注解: @Component, @Service, @Controller, @Repository

@Component是用于Spring管理的组件的泛型 stereotype。

@Repository, @Service, @Controller 是@Component的特例化,例如,其分别用于持久化,服务,表示层。

因此,我们可以使用@Component来注解我们的组件类;但是如果使用@Repository,@Service,@Controller这些注解,我们的类更加适合被相应的工具所处理,或者与特定的切面相关联。

元注解 - Meta-annotation

Spring提供的许多注解可以被用作“meta-annotations”。meta-annotation是一个简单的注解,其可以被应用在其他的注解上。例如@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 {

// ....

}


元注解可以组合起来创建一个复合注解,例如,@RestController注解是由@Controller和@ResponseBody注解组合起来的。

自动检测类,注册bean的定义

Spring会自动检测stereotype类,并在ApplicationContext中注册相应的bean definition

例如,如下的两个类可被自动检测到:

@Service
public class SimpleMovieLister {

private MovieFinder movieFinder;

@Autowired
public SimpleMovieLister(MovieFinder movieFinder) {
this.movieFinder = movieFinder;
}

}


@Repository
public class JpaMovieFinder implements MovieFinder {
// implementation elided for clarity
}


为了检测到这些类,并注册相应的beans,需要在@Configuration类中添加@ComponentScan,basePackages属性指定了扫描的paren package:

@Configuration
@ComponentScan(basePackages = "org.example")
public class AppConfig  {
...
}


或者,我们可以在XML配置文件中如下配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 
<context:component-scan base-package="org.example"/>

</beans>


<context:component-scan>隐式地激活了<context:anntation-config>功能。当使用<context:component-scan>元素时,不必再包含<context:annotation-config>

AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanProcessor当使用component-scan元素的时候会隐式地被包含进来。

使用filter来定制组件扫描

默认,被@Component, @Repository, @Service, @Controller或使用@Component注解的注解所注解时,是唯一可被检测到的组件/beans.

但是,我们可以通过应用自定义filter来修改或扩展这种行为。

在@ComponentScan注解中添加IncludeFilters或者excludeFilters参数,或者在component-scan元素中添加include-filter或者exclude-filter子元素,都可以实现这一功能。

每一个filter 元素需要包含type 和 expression 属性。

命名被自动检测的组件

当一个组件被自动检测到的时候,bean名称由BeanNameGenerator生成。默认的,Spring stereotype注解(@Component, @Repository, @Service, @Controller)可以包含一个name值,来指定这个bean的名字。

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


指定被自动检测的组件的作用域-Scope

默认,大部分自动检测到的组件的作用域是单件的。

但是,有时需要指定其他的scope。

可以使用@Scope注解指定新的作用域

@Scope("prototype")
@Repository
public class MovieFinderImpl implements MovieFinder {
// ...
}


当使用非单件的作用域,可能需要生成这些对象的代理。可以在component-scan element中使用scoped-proxy属性。可以使用三个属性值:no , interfaces, targetClass。例如:

@Configuration
@ComponentScan(basePackages = "org.example", scopedProxy = ScopedProxyMode.INTERFACES)
public class AppConfig {
...
}
<beans>
<context:component-scan base-package="org.example"
scoped-proxy="interfaces" />
</beans>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: