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

