标签:
Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载、实例化Bean,并建立Bean和Bean的依赖关系,最后将这些准备就绪的Bean放到Bean缓存池中,以供外层的应用程序进行调用。
bean配置有三种方法:
我们知道,Spring容器成功启动的三大要件分别是:Bean定义信息、Bean实现类以及Spring本身。如果采用基于XML的配置,Bean定义信息和Bean实现类本身是分离的,而采用基于注解的配置方式时,Bean定义信息即通过在Bean实现类上标注注解实现。
下面是使用注解定义一个DAO的Bean:
package com.baobaotao.anno; import org.springframework.stereotype.Component; import org.springframework.stereotype.Repository; //①通过Repository定义一个DAO的Bean @Component("userDao") public class UserDao { }
在①处,我们使用@Component注解在UserDao类声明处对类进行标注,它可以被Spring容器识别,Spring容器自动将POJO转换为容器管理的Bean。
它和以下的XML配置是等效的:
<bean id="userDao" class="com.baobaotao.anno.UserDao"/>
除了@Component以外,Spring提供了3个功能基本和@Component等效的注解,它们分别用于对DAO、Service及Web层的Controller进行注解,所以也称这些注解为Bean的衍型注解:
之所以要在@Component之外提供这三个特殊的注解,是为了让注解类本身的用途清晰化,此外Spring将赋予它们一些特殊的功能。
Spring提供了一个context的命名空间,它提供了通过扫描类包以应用注解定义Bean的方式:
<?xml version="1.0" encoding="UTF-8" ?> <!--①声明context的命名空间--> <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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd" > <!--②扫描类包以应用注解定义的Bean--> <context:component-scan base-package="com.baobaotao.anno"/> <bean class="com.baobaotao.anno.LogonService"></bean> <!-- context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ --> <!-- context:component-scan base-package="com.baobaotao"> <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Dao"/> <context:include-filter type="regex" expression="com\.baobaotao\.anno.*Service"/> <context:exclude-filter type="aspectj" expression="com.baobaotao..*Controller+"/> </context:component-scan --> </beans>
在①处声明context命名空间,在②处即可通过context命名空间的component-scan的base-package属性指定一个需要扫描的基类包,Spring容器将会扫描这个基类包里的所有类,并从类的注解信息中获取Bean的定义信息。
如果仅希望扫描特定的类而非基包下的所有类,你们可以使用resource-pattern属性过滤特定的类,如下所示:
< context:component-scan base-package="com.baobaotao" resource-pattern="anno/*.class"/ >
这里我们将基类包设置为com.baobaotao,默认情况下resource-pattern属性的值为"**/*.class",即基类包里的所有类。这里我们设置为"anno/*.class",则Spring仅会扫描基包里anno子包中的类。
在普通的POJO类中只要标注@Configuration注解,就可以为spring容器提供Bean定义的信息了,每个标注了@Bean的类方法都相当于提供了一个Bean的定义信息。
package com.baobaotao.conf; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; //①将一个POJO标注为定义Bean的配置类 @Configuration public class AppConf { //②以下两个方法定义了两个Bean,以提供了Bean的实例化逻辑 @Bean public UserDao userDao(){ return new UserDao(); } @Bean public LogDao logDao(){ return new LogDao(); } //③定义了logonService的Bean @Bean public LogonService logonService(){ LogonService logonService = new LogonService(); //④将②和③处定义的Bean注入到LogonService Bean中 logonService.setLogDao(logDao()); logonService.setUserDao(userDao()); return logonService; } }
①处在APPConf类的定义处标注了@Configuration注解,说明这个类可用于为Spring提供Bean的定义信息。类的方法处可以标注@Bean注解,Bean的类型由方法返回值类型决定,名称默认和方法名相同,也可以通过入参显示指定Bean名称,如@Bean(name="userDao").直接在@Bean所标注的方法中提供Bean的实例化逻辑。
在②处userDao()和logDao()方法定义了一个UserDao和一个LogDao的Bean,它们的Bean名称分别是userDao和logDao。在③处,又定义了一个logonService Bean,并且在④处注入②处所定义的两个Bean。
因此,以上的配置和以下XML配置时等效的:
<bean id="userDao" class="com.baobaotao.anno.UserDao"/> <bean id="logDao" class="com.baobaotao.anno.LogDao"/> <bean id="logService" class="com.baobaotao.conf.LogonService" p:logDao-ref="logDao" p:userDao-ref="userDao"/>
基于java类的配置方式和基于XML或基于注解的配置方式相比,前者通过代码的方式更加灵活地实现了Bean的实例化及Bean之间的装配,但后面两者都是通过配置声明的方式,在灵活性上要稍逊一些,但是配置上要更简单一些。
标签:
原文地址:http://www.cnblogs.com/wuchanming/p/5426746.html