(II)第十三节:使用注解创建Dao、Service、Controller Bean 组件

一、注解配置 bean

        相对于 XML 方式而言,通过注解的方式配置 bean 更加简洁和优雅,而且和 MVC 组件化开发的理念十分契合,是开发中常用的使用方式。
 

二、使用注解标识组件

  组件:即 Spring 中管理的 bean
  1)普通组件:@Component
                                标识一个受 Spring IOC 容器管理的组件;
        2)  持久化层组件:@Repository
                                标识一个受 Spring IOC 容器管理的持久化层组件;
        3)  业务逻辑层组件:@Service
                                标识一个受 Spring IOC 容器管理的业务逻辑层组件;
        4)  表示层控制器组件:@Controller
                                标识一个受 Spring IOC 容器管理的表示层控制器组件;
 
 

  使用注解将组件快速的加入到容器中需要几步

1)给需要添加的组件上标四个注解的任何一个
2)告诉Spring自动扫描加了注解的组件;依赖context名称空间
3)一定要导入aop包,才支持加注解模式

  

  组件命名规则
                ① 默认情况下,Spring IOC 容器帮我们生成的组件,使用组件的简单类名首字母小写后得到的字符串作为组件(bean) 的 id 值。
                ② 可以使用组件注解的 value 属性来指定该组件(bean)  id 值;
//组件的id默认为_组件类名首字母小写
@Controller("bookServletABC")或(value="bookServletABC")
public class BookServlet{}

  组件的作用域—默认为单例模式

    默认为单例模式,可以使用 @Scope 注解修改 bean 的作用域。

@Scope(value = "prototype")
  使用注解加入到容器中的组件,和使用配置加入到容器中的组件行为都是默认一样的。
  (1)组件的 id,默认就是组件的类名首字母小写;
  (2)组件的作用域,默认就是单例的;
 
  注意: 事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将 @Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以 @Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色

三、扫描组件

   使用注解标识了组件后,还需要通过 Spring 进行扫描才能侦测到。
        在 Spring 的配置文件中使用 <context> 标签指定被扫描的包
   context:component-scan:自动组件扫描
   base-package:指定扫描的基础包,把基础包及它下面所有的包的所有了加了注解的类,自动扫描进 ioc 容器。
<context:component-scan  base-package="com.spring.ioc" ></context:component-scan>

  

  详细说明:
            ① base-package 属性指定一个需要扫描的基类包,Spring 容器将会扫描这个基类包及其子包中的所有类;
            ② 当需要扫描多个包时可以使用逗号进行分割;
            ③ 如果仅希望扫描特定的类而非基包下的所有类,可使用 resource-pattern 属性过滤特定的类:
    示例:仅扫描 com.spring.ioc.user.service 下面的 java 类。
<context:component-scan  base-package="com.spring.ioc.user"  resource-pattern="service/*.class">
   注意:使用扫描器的时候必须要再导入一个:spring-aop-4.0.0.RELEASE.jar 依赖。     
 

四、使用context:include-filter指定扫描包时要包含的类—包含

  <context> 中有一个 use-default-filters 属性,该属性默认为 true,表示扫描该包下的所有类。

  <context:include-filter>子节点表示要包含的目标类。
  注意:使用这个子节点标签,一般都是配合 use-default-filters 属性来使用,这样才能达到“仅包含某些组件”,这样的效果。即需要把  use-default-filters 属性设置为 false,不使用默认过滤器(默认扫描全部),然后只扫描的就只是 include-filter 中的规则指定的组件。
  代码示例:
<--
    只扫描进那些组件;默认都是全部扫描
    一定要禁用掉默认的过滤规则才行:
    use-default-filters属性="false"
-->
<context:component-scan base-package="com.achang" use-default-filters="false">
    <!--指定只扫描那些组件-->
    <context:include-filter expression="org.springframework.stereotype.Service" type="annotation"/>
</context:component-scan>
   表达式:
 

【type="annotation"】:指定排除规则,按照注解进行包含或排除。标注指定注解的组件不要扫描
           expression属性:指定注解类型的全类名


【type=assignable】:指定排除某个具体的类,按照类排除
          expression属性:指定类的全类名
type=aspectj:后来aspectj表达式
type=custom:自定义一个TypeFilter;自己写代码觉得排除规则,编写一个类实现TypeFilter类的match()方法
tyoe=regex:正则表达式

 
过滤表达式:
类别
示例
说明
annotation
com.spring.XxxAnnotation
过滤所有标注了XxxAnnotation的类。这个规则根据目标组件是否标注了指定类型的注解进行过滤。
assignable
com.spring.BaseXxx
过滤所有BaseXxx类的子类。这个规则根据目标组件是否是指定类型的子类的方式进行过滤。
aspectj
com.spring.*Service+
所有类名是以Service结束的,或这样的类的子类。这个规则根据AspectJ表达式进行过滤。
regex
com\.spring\.anno\.*
所有com.atguigu.anno包下的类。这个规则根据正则表达式匹配到的类名进行过滤。
custom
com.spring.XxxTypeFilter
使用XxxTypeFilter类通过编码的方式自定义过滤规则。该类必须实现org.springframework.core.type.filter.TypeFilter接口
 
 

五、使用context:exclude-filter指定扫描包时不包含的类—排除

  <context> 中有一个 use-default-filters 属性,该属性默认为 true,表示扫描该包下的所有类。

  <context:exclude-filter>子节点表示要排除在外的目标类
  注意:这个标签用法同上,不同的是,use-default-filters 的值必须为 true,表示从全部扫描的组件中排除 exclude-filter 规则中指定的组件。
  <context: component-scan> 下可以拥又若干个 include-filter 和 exclude-filter 子节点,但是两者不能同时拥有
<--
    扫描的时候可以排除不要的组件
-->
<context:component-scan base-package="com.achang" use-default-filters="true">
   <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Service"/>
</context:component-scan>

六、代码示例

  DAO层:

package com.spring.ioc.User.dao;
import org.springframework.stereotype.Repository;

@Repository
public class UserDaoImpl implements IUserDao {
     public UserDaoImpl() {
         super();
         System.out.println("UserDaoImpl构造器");
     }

     @Override
     public void addUser() {
         System.out.println("UserDaoImpl:添加成功");
     }
}

  Service层:

package com.spring.ioc.User.service;
import org.springframework.stereotype.Service;
import com.spring.ioc.User.dao.IUserDao;
import com.spring.ioc.User.dao.UserDaoImpl;

@Service
public class UserServiceImpl implements IUserService {
     
     private IUserDao userDao = new UserDaoImpl();
     
     @Override
     public void addUser() {
         userDao.addUser();
     }
     public UserServiceImpl() {
         super();
         System.out.println("UserServiceImpl构造器");
     } 
}

  Controller层:

package com.spring.ioc.User.controller;
import org.springframework.stereotype.Controller;
import com.spring.ioc.User.service.IUserService;
import com.spring.ioc.User.service.UserServiceImpl;

@Controller
public class UserController {
     
     private IUserService userService = new  UserServiceImpl();
     
     public void addUser() {
         userService.addUser();
     }
     public UserController() {
         super();
     
         System.out.println("UserController构造器");
     }
     
}

  Spring 配置文件:

   <!-- 扫描器 使用 include-filter-->
     <context:component-scan  base-package="com.spring.ioc.User"  use-default-filters="false">
         <context:include-filter type="annotation"  expression="org.springframework.stereotype.Controller"/>  <!-- 扫描添加注解为 Controller 的类 -->
         <context:include-filter type="assignable"  expression="com.spring.ioc.User.service.IUserService"/> <!-- 扫描类型是 IUserService 的类或其子类 -->
     </context:component-scan>
     
     <!-- 扫描器 使用 exclude-filter-->
     <context:component-scan  base-package="com.spring.ioc.User"  use-default-filters="true">
         <context:exclude-filter type="annotation"  expression="org.springframework.stereotype.Controller"/>
         <context:exclude-filter type="assignable"  expression="com.spring.ioc.User.service.UserServiceImpl"/>
     </context:component-scan>
  说明
          ① <context:component-scan>:扫描组件,对设置的包下面的类进行扫苗,会将加上注解的类作为spring的组件进行加载
          ② 作为spring的组件进行加载:会自动在spring的配置文件中生成相对应的bean,这些bean的id会以类的首字母小写为值
          ③ <context:include-filter>:在设定的包结构下,再次通过注解或类型具体包含到某个或某几个类
            注意:在使用包含时,一定要设置use-default-filters="false",将默认的过滤(即扫描包下所有的类)关闭
          ④ <context:exclude-filter>:在设定的包结构下,再次通过注解或类型排除某个或某几个类
            注意:在使用排除时,一定要设置use-default-filters="true",将默认的过滤(即扫描包下所有的类)打开
          ⑤ 切记:一个<context:component-scan>中可以出现多个include,也可以出现多个exclude,但是两个不能同时出现

org.springframework.stereotype.Controller

原文地址:https://www.cnblogs.com/niujifei/p/15417965.html