1.基于注解配置bean
组件扫描:Spring 能够从classpath下自动扫描、侦测和实例化具有特定注解的组件。
特定组件包括:
@Component:基本注解,标识一个受Spring管理的组件
@Respository:标识持久层组件
@Service:标识服务层(业务层)组件
@Controller:标识表现层组件
这四个组件可以混用。对于扫描的组件,Spring有默认的命名策略:使用非限定类名,第一个字母小写。也可以在注解中通过value属性来标识组件的名称(value是默认属性,可以省略不写)
当在组件类上使用了特定的注解之后,还需要在Spring的配置文件中声明<context:component-scan>(需要导入context命名空间):
base-package:指定一个需要扫描的基类包,Spring容器会扫描这个基类包里及其子包里的所有类。
当需要扫描多个包时,需要用逗号分隔。
resource-pattern:如果仅希望扫描特定的类,而不是基包下的所有类,可使用它来过滤
<context:include-filter>:子节点表示要包含的目标类
<context:exclude-filter>:子节点表示要排除在外的目标类
<context:include-filter>和<context:exclude-filter>子节点支持的过滤表达式:(有五个,下面两个最常使用)
annotation:所有标注了XXXAnnotation的类,如org.springframework.stereotype.Controller
assignable: 所有继承或者扩展XXXService的类(根据具体的类名或者接口名)
例如:
</pre><p></p><p></p><p></p><p></p><pre code_snippet_id="1622980" snippet_file_name="blog_20160324_1_2437385" name="code" class="java"><!-- 确定Spring容器扫描的包 -->
<!--
resource-pattern = "controller/*.class" 扫描特定的类 即com.spring.hl.annotation.controller 下的类文件,
此时main.java文件中只能得到UserController类的bean,其他的都得不到,需要注释掉
<context:component-scan base-package="com.spring.hl.annotation" resource-pattern = "controller/*.class">
</context:component-scan>
-->
<!--
<context:component-scan base-package="com.spring.hl.annotation" use-default-filters = "false">
-->
<context:component-scan base-package="com.spring.hl.annotation" use-default-filters = "false">
<!-- context:exclude-filter 子节点指定排除哪些指定表达式的组件
此时Main.java 文件中的UserController类需要注释掉,否则会出错
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
-->
<!--
context:include-filter 子节点指定包含哪些表达式的组件,该子节点需要搭配 use-default-filters = "false" 使用,
否则看不到效果,
此时Main.java 文件中只保留UserController类,其他都需要注释掉,否则会出错
<context:component-scan base-package="com.spring.hl.annotation" use-default-filters = "false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
-->
<!-- 此时Main.java 文件中的UserRepository类需要注释掉,否则会出错
<context:exclude-filter type="assignable" expression="com.spring.hl.annotation.repository.RepositoryImpl"/>
-->
<!-- 此时Main.java 文件中只能保留UserRepository类,其他都需要注释掉,否则会出错 -->
<context:include-filter type="assignable" expression="com.spring.hl.annotation.repository.RepositoryImpl"/>
</context:component-scan>
<context:component-scan>下可以用于若干个<context:include-filter>和<context:exclude-filter>子节点。</span>
2.基于注解来配置bean的属性:配置bean与bean之间的关联关系
组件装配:<context:component-scan> 元素还会自动注册AutowiredAnnotationBeanPostProcessor实例,该实例可以自动装配具有@Autowired 和 @Resource ,@inject 注解的属性
@Autowired 注解自动装配具有兼容类型的单个Bean属性。
1>构造器、普通字段,一切具有参数的方法都可以应用@Autowired注解
2>默认情况下,所有使用@Autowired注解的属性都需要被设置(即都需要在IOC容器中存在)。当Spring找不到匹配的Bean装配属性时,会抛出异常。若某一属性允许不被设置,可以设置@Autowired注解的required属性为false。
3>默认情况下,当IOC容器中出现多个类型兼容的Bean时,通过类型的自动装配将无法工作。此时可以在@Qualifier注解里提供Bean的名称。
Spring允许对方法的入参标注@Qualifier,以指定注入的Bean的名称。也可以给符合的bean重命名,让bean的名字和属性名一致
4>@Autowired 注解可以应用在数组类型的属性上,此时Spring会把所有匹配的Bean进行自动装配。
5>@Autowired 注解可以应用在集合属性上,此时Spring读取该集合的类型信息,然后自动装配所有与之兼容的Bean。
6>@Autowired 注解用在java.util.Map上时,若该Map的键值为String,那么Spring将自动装配与之Map值类型兼容的Bean,此时的Bean的名称作
为键值。
@Autowired
public void setRepositoryImpl(@Qualifier("TTTTTTTTTTTTTTT") RepositoryImpl repositoryImpl) {
this.repositoryImpl = repositoryImpl;
}
@inject 按照类型匹配注入的Bean,但是没有required属性。
注意:@Autowire首先按照类型来查找符合条件的bean
1>如果没有找到符合条件的bean,则判断其required属性的取值,如果其取值为false,则程序仍然能正常运行,否则,程序会报错。
2>如果能找到符合条件的bean,且只有一个,则返回所找到的bean。如果找到符合条件的bean,且个数不止一个,则要根据bean的名称来选择一个最优解。
3>也可以配置@Qualifier,用它来指定选取特定名称的bean