zoukankan      html  css  js  c++  java
  • Spring注解@Repository、@Service、@Controller、@Component

    继前几章所讲解的注解中:

    http://www.cnblogs.com/EasonJim/p/6892280.html

    http://www.cnblogs.com/EasonJim/p/6899747.html

    http://www.cnblogs.com/EasonJim/p/6901115.html

    发现上述遗漏了一些注解,比如:@Repository、@Service、@Controller、@Component,现在做如下补充:

    Spring自2.0版本开始,陆续引入了一些注解用于简化Spring的开发。到了2.5版本时才大量引入更全面的注解功能。@Repository注解便属于最先引入的一批,它用于将数据访问层(DAO 层)的类标识为Spring Bean。具体只需将该注解标注在DAO类上即可。同时,为了让Spring能够扫描类路径中的类并识别出@Repository注解,需要在XML配置文件中启用Bean的自动扫描功能,这可以通过<context:component-scan/>实现。如下所示:

     //首先使用 @Repository 将 DAO 类声明为 Bean 
     package com.jsoft.dao; 
     @Repository 
     public class UserDaoImpl implements UserDao{ …… } 
    <!--其次,在XML配置文件中启动Spring的自动扫描功能-->
    <beans > 
        ……
        <context:component-scan base-package=”com.jsoft.dao” /> 
        ……
    </beans> 

    如此,我们就不再需要在XML中显式使用<bean/>进行Bean的配置。Spring在容器初始化时将自动扫描base-package指定的包及其子包下的所有class文件,所有标注了@Repository的类都将被注册为Spring Bean。

    为什么@Repository只能标注在DAO类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为Spring的数据访问异常类型。Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。

    Spring 2.5在@Repository的基础上增加了功能类似的额外三个注解:@Component、@Service、@Constroller,它们分别用于软件系统的不同层次:

    • @Component是一个泛化的概念,仅仅表示一个组件 (Bean) ,可以作用在任何层次。
    • @Service通常作用在业务层,但是目前该功能与@Component相同。
    • @Constroller通常作用在控制层,但是目前该功能与@Component相同。

    通过在类上使用@Repository、@Component、@Service和@Constroller注解,Spring会自动创建相应的BeanDefinition对象,并注册到ApplicationContext中。这些类就成了Spring受管组件。这三个注解除了作用于不同软件层次的类,其使用方式与@Repository是完全相同的。

    另外,除了上面的四个注解外,用户可以创建自定义的注解,然后在注解上标注@Component,那么,该自定义注解便具有了与所@Component相同的功能。不过这个功能并不常用。

    当一个Bean被自动检测到时,会根据那个扫描器的BeanNameGenerator策略生成它的Bean名称。默认情况下,对于包含name属性的@Component、@Repository、 @Service和@Controller,会把name取值作为Bean的名字。如果这个注解不包含name值或是其他被自定义过滤器发现的组件,默认Bean名称会是小写开头的非限定类名。如果你不想使用默认Bean命名策略,可以提供一个自定义的命名策略。首先实现BeanNameGenerator接口,确认包含了一个默认的无参数构造方法。然后在配置扫描器时提供一个全限定类名,如下所示:

    <beans ...> 
        <context:component-scan base-package="a.b" name-generator="a.SimpleNameGenerator"/> 
    </beans> 

    与通过XML配置的Spring Bean一样,通过上述注解标识的Bean,其默认作用域是"singleton"(单例),为了配合这四个注解,在标注Bean的同时能够指定Bean的作用域,Spring2.5引入了@Scope注解。使用该注解时只需提供作用域的名称就行了,如下所示:

    @Scope("prototype") 
    @Repository 
    public class Demo { … } 

    如果你想提供一个自定义的作用域解析策略而不使用基于注解的方法,只需实现ScopeMetadataResolver接口,确认包含一个默认的没有参数的构造方法。然后在配置扫描器时提供全限定类名:

    <context:component-scan base-package="a.b" scope-resolver="a.SimpleScopeResolver" /> 

    简单例子:

    DAO层

    package com.jsoft.dao;
    
    public interface UserDao {
        public void save();
    }

    DAO层实现类

    package com.jsoft.dao.impl;
    
    import org.springframework.stereotype.Repository;
    
    import com.jsoft.dao.UserDao;
    
    @Repository
    public class UserDaoImpl implements UserDao {
        @Override
        public void save() {
            System.out.println("测试保存");
        }
    }

    Service层

    package com.jsoft.service;
    
    public interface UserService {
        public void Usersave();
    }

    Service实现类

    package com.jsoft.service.Impl;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    import com.jsoft.dao.UserDao;
    import com.jsoft.service.UserService;
    
    @Service
    public class UserServiceImpl implements UserService{
        @Autowired//自动注入
        UserDao userDao;
    
        @Override
        public void Usersave() {
            System.out.println("Service执行保存方法");
            userDao.save();
        }
        
    }

    DTO中间类

    package com.jsoft.dto;
    
    import org.springframework.stereotype.Component;
    
    @Component
    public class DtoClass {
        public void say(){
            System.out.println("我是DTO");
        }
    }

    控制层

    package com.jsoft.Controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    
    import com.jsoft.dto.DtoClass;
    import com.jsoft.service.UserService;
    
    @Controller
    public class UserController {
        @Autowired
        private UserService userService;
        @Autowired
        public DtoClass dtoClass;
    
        public void save(){
            System.out.println("控制层save");
            dtoClass.say();
            userService.Usersave();
        }
    }

    测试类

    package com.jsoft.test.autoTest;
    
    import org.junit.Before;
    import org.junit.Test;
    import org.springframework.context.ApplicationContext;
    import com.jsoft.Controller.UserController;
    import com.jsoft.util.SpringUtil;
    
    public class MyTest {
        ApplicationContext applicationContext = null;
    
        @Before
        public void before() {
            applicationContext = SpringUtil.getApplicationContext();
        }
    
        @Test
        public void controller(){
            UserController controller = applicationContext.getBean(UserController.class);
            controller.save();
        }
    }

    参考:

    http://blog.csdn.net/ye1992/article/details/19971467

    http://www.cnblogs.com/lonecloud/p/5745885.html

  • 相关阅读:
    CAS 5.X 安装
    《从0到1》开启商业和未来的秘密
    阿里Java开发规约插件使用
    【Effective Java】阅读
    Java8 流的使用示例
    我对线程安全的理解
    APP微信支付实现
    如何将微信上传AMR格式语音转化为MP3格式
    如何在下载文件前确定文件名
    寻找水王1
  • 原文地址:https://www.cnblogs.com/EasonJim/p/7347534.html
Copyright © 2011-2022 走看看