天问

​Spring 自动扫描与自动装配



Spring 自动扫描与自动装配(Autowiring)

今天学习 Spring 框架中的自动扫描组件与自动装配相关知识点。

Spring有几种属性来设置具体的装配


  1. No ---- 不做任何操作,通过 ref attribute手动设定。

  2. byname ---- 根据属性名(Property Name)自动装配。此选项将检查容器并根据名字查找与属性完全一致的另一个bean,并将其与属性自动装配

  3. byType ---- 如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配;如果存在多个该类型的bean,那么抛出异常,并指出不能使用byType方式进行自动装配;如果没有找到相匹配的bean,则什么事都不发生

  4. Constructor ---- 与byType方式类似,不同之处在于它应用于构造器参数。如果容器中没有找到与构造器参数类型一致的bean,那么抛出异常

  5. autodetect ---- 如果发现默认的构造函数,用 constructor 模式,否则,用 byType 模式。


Bean的自动装配:在beans标签配置属性 default-autowire="no/byName/byType/constructor"

作用:省去了在Spring的xml中配置property标签和constructor-arg标签,只需要配置bean标签即可

PS:byName和byType为设值注入,constructor为构造注入;byName要求bean标签的id属性需要和成员变量的名称一致,byType和constructor则跟id无关


通常可以在 xml 配置文件中,声明一个 bean 或者 component ,然后 Spring 容器会检查和注册你的 bean 或 component 。实际上Spring 支持自动扫描 bean 或 component ,不必再在 xml 文件中繁琐的声明 bean ,Spring 会自动扫描、检查你指定包的 bean 或 component 。


写个简单的手动配置的Spring Project ,使用maven来创建,包含Customer,Service,DAO层,以上不做具体业务实现,只是进行声明测试.

创建maven项目

修改pom.xml,添加Spring依赖

    <dependencies>     <dependency>         <groupId>org.springframework</groupId>         <artifactId>spring-context</artifactId>         <version>4.3.4.RELEASE</version>     </dependency> </dependencies>

CustomerDAO类

package net.boy.spring.SpringAuto;  public class CustomerDAO {      @Override     public String toString() {         return "This is CustomerDAO ";     }   }

CustomerService类

package net.boy.spring.Services;  import net.boy.spring.SpringAuto.CustomerDAO;  public class CustomerService {      CustomerDAO customerDAO;      public void setCustomerDAO(CustomerDAO customerDAO) {         this.customerDAO = customerDAO;     }      @Override     public String toString() {         return "CustomerService : customerDAO = " + customerDAO;     }  }

在main下创建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"        xsi:schemaLocation="http://www.springframework.org/schema/beans            http://www.springframework.org/schema/beans/spring-beans.xsd">              <bean id="customerService" class="net.boy.spring.Services.CustomerService">                 <property name="customerDAO" ref="customerDAO"></property>             </bean>              <bean id="customerDAO" class="net.boy.spring.SpringAuto.CustomerDAO">            </bean>     </beans>

创建App测试类

package net.boy.spring.SpringAuto;  import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import net.boy.spring.Services.CustomerService;  public class App{      public static void main(String[] args) {         ApplicationContext context =                  new ClassPathXmlApplicationContext(new String[] {"springAuto.xml"});          CustomerService service = (CustomerService) context.getBean("customerService");         System.out.println(service);     }   }

以上为手工配置方式,实现默认装配可配置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"     xsi:schemaLocation="http://www.springframework.org/schema/beans         http://www.springframework.org/schema/beans/spring-beans.xsd"          default-autowire="constructor">      </beans>

通过default-autowire="constructor"属性设置装配模式,属性值分别是前面的几种方式,对于不同属性进行不同的注入方式,这种就省去了<property></property>的声明.Spring自动装


但是还有使用@Component注解来表示这个Class是一个自动扫描组件,而且Spring还是鼓励这种方式来实现,来减少配置文件的大小,增加程序的紧密性.

上面的Class使用@Component注解

配置xml文件

<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/context                 http://www.springframework.org/schema/context/spring-context.xsd             http://www.springframework.org/schema/beans              http://www.springframework.org/schema/beans/spring-beans.xsd">       <context:component-scan base-package="net.boy.spring" />  </beans>

context:component-scan 标签 ,Spring将自动扫描特性引入;base-package 表示组件的存放位置,Spring 将扫描对应文件夹下的 bean(用 @Component 注释过的),将这些 bean 注册到容器中。

默认情况下.Spring 将把组件 Class 的第一个字母变成小写,来作为自动扫描组件的名称.

如下

super.getBean("beanScope");

自定义扫描组件名称

@Service("boy") public class BeanScope  

现在变成

super.getBean("boy");

自动扫描组件的注释类型

有 4 种注释类型,分别是:

@Component ——表示一个自动扫描 component

@Repository ——表示持久化层的 DAO component

@Service ——表示业务逻辑层的 Service component

@Controller ——表示表示层的 Controller compone

自动扫描中过滤组件

Filter Component - include

组件只要匹配定义的"regex"的命名规则,Class 前就不需要用 @Component 进行注释。

    <context:component-scan base-package="net.boy.spring" >          <context:include-filter type="regex"                         expression="net.boy.spring.*Bean.*" />        </context:component-scan>

Filter Component——exclude

制定组件避免被 Spring 发现并被注册到容器中。以下配置排除用 @Service 注释过的组件:

<context:component-scan base-package="net.boy.spring" >         <context:exclude-filter type="annotation"              expression="org.springframework.stereotype.Service" />         </context:component-scan>

使用JAVA正则

<context:component-scan base-package="com.lei" >         <context:exclude-filter type="regex"              expression="net.boy.spring.dao.*DAO.*" />         </context:component-scan>

使用自动装配大大提高开发效率,但是提高了配置文件的复杂性.先整理这么多,以后多多运用来加深理解..

博客地址:http://blog.yoqi.me/?p=1322
扫我捐助哦
喜欢 0

这篇文章还没有评论

发表评论