Spring @ Component,@ Service,@ Repository,@ Controller注释
与其在Spring XML Configuration中提供bean定义和依赖关系,不如使Spring框架本身通过扫描类路径并在容器中注册相应的bean定义来自动检测类。可以使用Spring @Component注释(这是通用注释)以及@ Repository,@ Service和@Controller(这是@Component的特化)来完成的。
Spring中的原型注释
对于具有特定角色的任何Spring管理的组件,Spring都有构造型注释。在Spring中,这些构造型注释为@ Component,@ Service,@ Repository和@Controller。
Spring @Component注释
@Component是任何Spring托管组件的通用构造型。如果我们有任何带有@Component注释的类,则组件扫描将检测到该类并将其注册为Spring容器中的Bean。
@Component public class UserService { ... ... }
如前所述,它是一个通用的构造型注释,根据角色的不同,这些注释还有进一步的专业化,建议使用这些注释。此外,根据Spring文档,这些特殊的构造型注释也可能在Spring框架的未来版本中带有其他语义。
Spring @Service注释
服务层中的任何类都应使用@Service注释进行注释,尽管使用@Service而不是@Component的唯一好处是可读性更高。
Spring @Repository注释
DAO(数据访问对象)层中充当存储库角色的任何类都应使用@Repository注释进行注释。 @Repository的用途之一是自动转换底层持久性技术引发的异常。基础持久性技术引发的任何异常都包装在DataAccessException实例中。
Spring @Controller注释
在Spring Web MVC应用程序中充当控制器的任何类都应使用@Controller注释进行注释。
因此,经验法则不是使用通用构造型注释,而是根据分层体系结构中的类使用更具体的注释。
表示层@控制器
服务层@服务
持久层@存储库
Presentation layer@Controller
Service layer@Service
Persistence layer@Repository
配置以启用组件扫描
如果使用XML配置,则需要在XML中使用<context:component-scan>元素,它将Spring配置为自动发现bean并为我们声明它们。这消除了使用XML提供bean定义的需要。
<context:component-scan>元素需要基本包装属性。使用base-package属性,我们需要指定必须从中进行递归组件扫描的起始包。
例如,如果服务类包含在com.theitroad.springexample.service包中,而DAO类则包含在com.theitroad.springexample.dao包中,则必须提供基本包作为com.theitroad.springexample,并且两个-packages服务和dao将被递归扫描。
<context:component-scan base-package="com.theitroad.springexample"/>
如果我们使用的是Spring Java配置,则需要添加@ComponentScan注释以及@Configuration注释。
@Configuration @ComponentScan(basePackages="com.theitroad.springexample") public class AppConfig { }
Spring @ Component,@ Service,@ Repository注释示例
在示例中,我们将使用分层体系结构,其中com.theitroad.springexample.dao包包含DAO类,com.theitroad.springexample.service包包含Service类,com.theitroad.springexample.dto包包含数据传输对象。
UserService介面
import java.util.List; import com.theitroad.springexample.dto.User; public interface UserService { public List<User> getUsers(); }
UserServiceImpl类
import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.theitroad.springexample.dao.UserDAO; import com.theitroad.springexample.dto.User; @Service("userService") public class UserServiceImpl implements UserService{ @Autowired UserDAO userDAO; public List<User> getUsers() { return userDAO.getUsers(); } }
请注意此处使用@Service注释。还使用@Service指定名称,这意味着将使用该名称注册Bean。
UserDAO界面
import java.util.List; import com.theitroad.springexample.dto.User; public interface UserDAO { public List<User> getUsers(); }
UserDAOImpl类
import java.util.ArrayList; import java.util.List; import org.springframework.stereotype.Repository; import com.theitroad.springexample.dto.User; @Repository public class UserDAOImpl implements UserDAO { public List<User> getUsers() { System.out.println("In getUsers method, connect to DB and get data"); List<User> userList = new ArrayList<User>(); // Creating User instance locally User user = new User(); user.setFirstName("John"); user.setLastName("Wick"); user.setAge(35); userList.add(user); return userList; } }
注意此处使用@Repository注释。
DTO类(User.java)
public class User { private String firstName; private String lastName; private int age; public String getFirstName() { return firstName; } public String getLastName() { return lastName; } public int getAge() { return age; } public void setFirstName(String firstName) { this.firstName = firstName; } public void setLastName(String lastName) { this.lastName = lastName; } public void setAge(int age) { this.age = age; } }
配置类
import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; @Configuration @ComponentScan(basePackages="com.theitroad.springexample") public class AppConfig { }
要运行此示例,请使用以下类
public class App { public static void main(String[] args) { AbstractApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); UserService userService = context.getBean("userService", UserService.class); List<User> users = userService.getUsers(); for(User user : users) { System.out.println("First Name- " + user.getFirstName()); System.out.println("Last Name- " + user.getLastName()); System.out.println("Age- " + user.getAge()); } context.close(); } }
输出:
In getUsers method, connect to DB and get data First Name- John Last Name- Wick Age- 35