Câu hỏi Sự khác biệt giữa @Component, @Repository & @Service chú thích trong mùa xuân là gì?


Có thể @Component, @Repository và @Service chú thích được sử dụng thay thế cho nhau trong mùa xuân hoặc chúng có cung cấp bất kỳ chức năng cụ thể nào ngoài việc hoạt động như một thiết bị ký hiệu?

Nói cách khác, nếu tôi có một lớp Dịch vụ và tôi thay đổi chú thích từ @Service đến @Component, nó vẫn sẽ hành xử theo cùng một cách?

Hay chú thích cũng ảnh hưởng đến hành vi và chức năng của lớp?


1523
2017-07-26 09:10


gốc


Là một nhà phát triển với nền tảng của Microsoft, tôi nhớ lại định nghĩa ngữ nghĩa của các dịch vụ trong khung công tác MS SmartClientSoftwareFactory cũ (hiện nay là một khung công tác phức tạp không còn được dùng lâu dài cho các ứng dụng máy tính để bàn phân tán). Định nghĩa đó (tài liệu đẹp bởi Rich Newman) đã định nghĩa các dịch vụ là các đối tượng tái sử dụng không quốc tịch, tốt nhất là với phạm vi singleton, được sử dụng để thực hiện các phép toán logic nghiệp vụ trên các đối tượng khác được truyền làm đối số. Tôi có xu hướng xem các dịch vụ Spring theo cùng một cách - Ivaylo Slavov
Không quan trọng !! Bất cứ điều gì làm việc cho bạn :) Tôi đã luôn luôn ghét điều này về mùa xuân mà họ luôn luôn có xu hướng xác định "quy tắc" cho bạn, mà chỉ thêm giá trị tầm thường cho ứng dụng của bạn. Chưa kể đến mùa xuân đi kèm với đống lớn của riêng mình. - TriCore
@TriCore Sprting là một khuôn khổ, xác định "quy tắc" cho bạn là công việc của mình :) - Walfrat


Các câu trả lời:


Từ Tài liệu mùa xuân:

Vào mùa xuân 2.0 trở lên, @Repository chú thích là một điểm đánh dấu cho   bất kỳ lớp nào đáp ứng vai trò hoặc khuôn mẫu (còn được gọi là Dữ liệu   Access Object hoặc DAO) của một kho lưu trữ. Trong số các công dụng của điểm đánh dấu này   là bản dịch tự động của ngoại lệ.

Spring 2.5 giới thiệu thêm các chú thích về khuôn mẫu: @Component,    @Service@Controller. @Component là một khuôn mẫu chung cho bất kỳ   Thành phần do Spring quản lý. @Repository, @Service@Controller là   chuyên môn của @Component cho các trường hợp sử dụng cụ thể hơn, cho   ví dụ, trong lớp kiên trì, dịch vụ và bản trình bày,   tương ứng.

Do đó, bạn có thể chú thích các lớp thành phần của mình bằng @Component,   nhưng bằng cách chú thích chúng bằng @Repository, @Service, hoặc là @Controller   thay vào đó, các lớp của bạn phù hợp hơn để xử lý bằng các công cụ   hoặc liên kết với các khía cạnh. Ví dụ: các chú thích khuôn mẫu này   tạo mục tiêu lý tưởng cho các phím tắt.

Vì vậy, nếu bạn đang lựa chọn giữa việc sử dụng @Component hoặc là @Service cho   lớp dịch vụ của bạn, @Service rõ ràng là lựa chọn tốt hơn. Tương tự,   như đã nêu ở trên, @Repository đã được hỗ trợ làm điểm đánh dấu cho   dịch ngoại lệ tự động trong lớp kiên trì của bạn.

┌────────────┬─────────────────────────────────────────────────────┐
│ Annotation │ Meaning                                             │
├────────────┼─────────────────────────────────────────────────────┤
│ @Component │ generic stereotype for any Spring-managed component │
│ @Repository│ stereotype for persistence layer                    │
│ @Service   │ stereotype for service layer                        │
│ @Controller│ stereotype for presentation layer (spring-mvc)      │
└────────────┴─────────────────────────────────────────────────────┘

1119
2017-08-01 10:20



Có thể thêm @Controller (hoặc @Component) vào một @WebServlet không? Nó không phải là một bộ điều khiển MVC Spring, nhưng đó là trận đấu gần nhất về khái niệm. Điều gì về bộ lọc servlet? - Rick
"@Repository đã được hỗ trợ làm điểm đánh dấu cho bản dịch ngoại lệ tự động trong lớp kiên trì của bạn." nghĩa là? - Jack
Nó đề cập đến thực tế là các chú thích này là mục tiêu tốt cho AOP và trong khi các chú thích khác không xác định được một điểm nhấn, chúng có thể làm điều đó trong tương lai. Mặt khác @Repository đã là một mục tiêu cho một điểm cắt hiện nay. Đường cắt đó được sử dụng cho các bản dịch ngoại lệ, tức là dịch các ngoại lệ dành riêng cho công nghệ thành các ngoại lệ chung dựa trên Spring, để tránh khớp nối chặt chẽ. - stivlo
@stivlo: Tôi đã thực sự cố gắng hiểu thuật ngữ 'khuôn mẫu', vẫn chưa hiểu. Bạn có thể giúp tôi hiểu thuật ngữ này không? Nó giúp ích rất nhiều và cảm ơn bạn rất nhiều - Premraj
stackoverflow.com/questions/14756486/… - stivlo


Vì nhiều câu trả lời đã nêu rõ những chú thích này được sử dụng để làm gì, chúng tôi sẽ tập trung vào một số khác biệt nhỏ giữa chúng.

Đầu tiên Tương tự 

Điểm đáng chú ý đầu tiên một lần nữa là đối với quét tự động phát hiện và phụ thuộc tiêm cho BeanDefinition tất cả các chú thích này (viz., @Component, @Service,   @Repository, @Controller) giống nhau. Chúng ta có thể sử dụng một cái tại chỗ   của người khác và vẫn có thể có được cách của chúng tôi xung quanh.


Sự khác biệt giữa @Component, @Repository, @Controller và @Service

@Component

Đây là một chú giải khuôn mẫu chung cho mục đích chỉ ra rằng lớp là một thành phần mùa xuân.

Điều đặc biệt về @Component
<context:component-scan> chỉ quét @Component và không tìm kiếm @Controller, @Service và @Repository nói chung. Chúng được quét bởi vì bản thân chúng được chú thích bằng @Component.

Chỉ cần nhìn vào @Controller, @Service và @Repository định nghĩa chú thích:

@Component
public @interface Service {
    ….
}

@Component
public @interface Repository {
    ….
}

@Component
public @interface Controller {
    …
}

Do đó, không có gì sai khi nói rằng @Controller, @Service và @Repository là loại đặc biệt của @Component chú thích. <context:component-scan> chọn chúng và đăng ký các lớp sau của chúng dưới dạng hạt, giống như chúng được chú thích @Component.

Chúng được quét bởi vì bản thân chúng được chú thích bằng @Component chú thích. Nếu chúng tôi định nghĩa chú thích tùy chỉnh của riêng mình và chú thích nó bằng @Component, sau đó nó cũng sẽ được quét với <context:component-scan>


@Kho

Điều này là để chỉ ra rằng lớp định nghĩa một kho dữ liệu.

Có gì đặc biệt về @Repository? 

Ngoài việc chỉ ra rằng đây là một Cấu hình dựa trên chú thích, @RepositoryCông việc của họ là bắt các ngoại lệ cụ thể của nền tảng và ném lại chúng như một ngoại lệ không được kiểm soát thống nhất của Spring. Và vì điều này, chúng tôi được cung cấp PersistenceExceptionTranslationPostProcessor, chúng tôi được yêu cầu thêm vào bối cảnh ứng dụng của Spring như sau:

<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

Bộ xử lý bài đăng bean này thêm một cố vấn cho bất kỳ bean nào được chú thích bằng @Repository để bất kỳ trường hợp ngoại lệ cụ thể theo nền tảng nào bị bắt và sau đó được coi là một trong những ngoại lệ truy cập dữ liệu không được kiểm soát của Spring.


@Controller

Các @Controller chú thích chỉ ra rằng một lớp cụ thể phục vụ vai trò của một bộ điều khiển. Các @Controller chú thích hoạt động như một khuôn mẫu cho lớp được chú thích, cho biết vai trò của nó.

Điều gì đặc biệt về @Controller? 

Chúng tôi không thể chuyển đổi chú thích này với bất kỳ chú thích nào khác @Service hoặc là @Repository, mặc dù chúng trông giống nhau. Người điều phối quét các lớp được chú thích bằng @Controller và phát hiện @RequestMapping chú thích bên trong chúng. Chúng tôi chỉ có thể sử dụng @RequestMapping trên @Controller các lớp được chú thích.


@Dịch vụ

@Services giữ logic nghiệp vụ và phương thức gọi trong tầng kho lưu trữ.

Có gì đặc biệt về @Service? 

Ngoài thực tế là nó được sử dụng để chỉ ra rằng nó giữ logic kinh doanh, không có đặc sản đáng chú ý mà chú thích này cung cấp, nhưng ai biết được, mùa xuân có thể thêm một số đặc biệt bổ sung trong tương lai.


Còn gì nữa?

Tương tự như trên, trong tương lai, mùa xuân có thể chọn thêm các chức năng đặc biệt cho @Service, @Controller và @Repository dựa trên các quy ước phân lớp của họ. Do đó nó luôn luôn là một ý tưởng tốt để tôn trọng các quy ước và sử dụng chúng phù hợp với các lớp.


426
2017-07-24 06:43



Đây là cái tôi thích nhất. Có rất nhiều câu trả lời hay cho câu hỏi này và tôi không khuyến khích bạn đọc tất cả, nhưng điều này nhấn mạnh sự khác biệt giữa các chú thích. - Adrian Cosma
lời giải thích ngắn gọn đẹp - VedX
Không có từ nào để chiêm ngưỡng câu trả lời này. Mỗi câu lệnh đều rõ ràng và dễ hiểu. - MAC
Lời giải thích được đưa ra ở đây là ngắn gọn và chính xác. Đây là câu trả lời thỏa đáng duy nhất mà tôi đã có - Julius Krah
Đây là câu trả lời. - Alessandro


Chúng gần như giống nhau - tất cả chúng có nghĩa là lớp đó là một bean Spring. @Service, @Repository và @Controller chuyên môn @ComponentS. Bạn có thể chọn thực hiện các hành động cụ thể với họ. Ví dụ:

  • @Controller đậu được sử dụng bởi spring-mvc
  • @Repository đậu có đủ điều kiện cho bản dịch ngoại lệ kiên trì

Một điều nữa là bạn chỉ định các thành phần ngữ nghĩa cho các lớp khác nhau.

Một điều mà @Component phiếu mua hàng là bạn có thể chú thích các chú thích khác với chú thích và sau đó sử dụng chúng giống như cách @Service.

Ví dụ gần đây tôi đã thực hiện:

@Component
@Scope("prototype")
public @interface ScheduledJob {..}

Vì vậy, tất cả các lớp được chú thích bằng @ScheduledJob là đậu mùa xuân và ngoài ra được đăng ký là công việc thạch anh. Bạn chỉ cần cung cấp mã để xử lý chú thích cụ thể.


388
2017-07-26 09:16



@Component có nghĩa là chỉ có đậu mùa xuân, là bất kỳ mục đích nào khác cho nó? - kapil das
@Component đậu được tự động phát hiện bởi container mùa xuân. Bạn không cần phải định nghĩa bean trong tệp cấu hình, nó sẽ tự động được phát hiện khi chạy theo Spring. - Akash5288
Tôi khá thích @Component chung ... đặc biệt là trong combo với @Scope (proxyMode = ScopedProxyMode.//MODE) - Eddie B


@Component tương đương với

<bean>

@Service, @Controller, @Repository = {@Component + một số chức năng đặc biệt khác}

Nghĩa là Service, Controller và Repository có chức năng giống nhau.

Ba chú thích được sử dụng để tách biệt "Lớp" trong ứng dụng của bạn,

  • Bộ điều khiển chỉ thực hiện các công cụ như gửi, chuyển tiếp, gọi phương thức dịch vụ, v.v.
  • Dịch vụ giữ kinh doanh Logic, tính toán vv
  • Kho lưu trữ là các DAO (đối tượng truy cập dữ liệu), chúng truy cập trực tiếp vào cơ sở dữ liệu.

Bây giờ bạn có thể hỏi lý do tại sao tách chúng: (Tôi giả sử bạn biết AOP-Aspect định hướng lập trình)

Giả sử bạn muốn Giám sát hoạt động của lớp DAO chỉ. Bạn sẽ viết một lớp Aspect (A class) thực hiện một số việc đăng nhập trước và sau mỗi phương thức DAO của bạn được gọi, bạn có thể làm điều đó bằng cách sử dụng AOP vì bạn có ba Lớp riêng biệt và không được trộn lẫn.

Vì vậy, bạn có thể làm đăng nhập của DAO "xung quanh", "trước" hoặc "sau" các phương pháp DAO. Bạn có thể làm điều đó bởi vì bạn đã có một DAO ở nơi đầu tiên. Những gì bạn vừa đạt được là Tách mối quan tâm hoặc nhiệm vụ.

Hãy tưởng tượng nếu chỉ có một chú thích @Controller, thì thành phần này sẽ có công văn, logic nghiệp vụ và cơ sở dữ liệu truy cập tất cả các mã hỗn hợp, quá bẩn!

Ở trên được đề cập là một kịch bản rất phổ biến, có nhiều trường hợp sử dụng hơn về lý do tại sao sử dụng ba chú thích.


333
2018-05-23 05:15



Tôi có một câu hỏi cơ bản - là các chú thích được sử dụng bởi cơ chế mùa xuân hoặc chúng chỉ dành cho lập trình viên để nhớ những đoạn mã đó làm gì? - user107986
@ user107986 Chúng chủ yếu dành cho Lập trình viên để ghi nhớ các lớp trong ứng dụng. Tuy nhiên @Respository cũng có tính năng dịch ngoại lệ tự động. Giống như khi một ngoại lệ xảy ra trong @Repository thường có một trình xử lý cho ngoại lệ đó và không cần phải thêm các khối catch thử trong lớp DAO. Nó được sử dụng cùng với PersistenceExceptionTranslationPostProcessor - Oliver
bạn có thể vui lòng viết một mã mẫu làm thế nào để viết một điểm chung cho tất cả các lớp "@ Lưu trữ". Hoặc chúng ta sử dụng các biểu thức hoặc sử dụng tên bean nhưng cách chúng ta có thể nói lời khuyên này sẽ áp dụng trên tất cả các lớp "@Repository". Tôi đã cố lấy mẫu này nhưng không thể tìm thấy. Trợ giúp của bạn thực sự được đánh giá cao. - Moni
Ngoài ra, trong khi các chú thích tất cả hiện đang hoạt động cùng chức năng, có thể chức năng cụ thể cho một thuộc tính nhất định có thể được thêm vào trong tương lai. - Cod3Citrus


Vào mùa xuân @Component, @Service, @Controller@Repository là các chú thích Khuôn mẫu được sử dụng cho:

@Controller: nơi bạn yêu cầu  ánh xạ từ trang bản trình bày thực hiện nghĩa là Lớp trình bày sẽ không chuyển đến bất kỳ tệp nào khác mà nó chuyển trực tiếp đến @Controller lớp và kiểm tra đường dẫn được yêu cầu trong @RequestMapping chú thích được viết trước cuộc gọi phương thức nếu cần.

@Service: Tất cả logic nghiệp vụ ở đây tức là tính toán liên quan đến dữ liệu và chú thích all.This của lớp nghiệp vụ mà người dùng của chúng tôi không trực tiếp gọi phương thức persistence để nó gọi phương thức này bằng chú thích này. Nó sẽ yêu cầu @Repository theo yêu cầu của người dùng

@Repository: Đây là lớp Persistence (Lớp truy cập dữ liệu) của ứng dụng dùng để lấy dữ liệu từ cơ sở dữ liệu. I E. tất cả các hoạt động liên quan đến cơ sở dữ liệu được thực hiện bởi kho lưu trữ.

@Component - Chú thích các thành phần khác của bạn (ví dụ: các lớp tài nguyên REST) ​​với một khuôn mẫu thành phần.

Chỉ ra rằng một lớp được chú thích là một "thành phần"Các lớp như vậy   được coi là ứng cử viên cho phát hiện tự động khi sử dụng   cấu hình dựa trên chú thích và quét đường dẫn lớp.

Các chú thích cấp lớp khác có thể được coi là xác định   thành phần là tốt, thường là một loại thành phần đặc biệt: ví dụ: các   Chú thích @Repository hoặc chú thích @Aspect của AspectJ.

enter image description here


188
2018-03-25 08:00



Tất cả những câu trả lời này đều tốt đẹp và tất cả, nhưng im khá chắc chắn những gì chúng ta muốn là một số ví dụ về các tính năng mà các thành phần như cung cấp dịch vụ mà chúng ta có thể đặt vào đầu của chúng ta một cách cụ thể hơn là mô tả chung như "logic nghiệp vụ" đối tượng này. nếu không, chúng tôi vẫn giả sử "oh đó là tuyệt vời và tất cả mọi thứ nhưng tôi vẫn có thể áp dụng cùng một mã cho thành phần" - dtc
không phải tất cả các logic kinh doanh nên đi vào dịch vụ! Các dịch vụ, về DDD, chỉ nên chứa logic miền ảnh hưởng đến nhiều hơn một thực thể. Xem câu trả lời stackoverflow.com/a/41358034/238134 - deamon
@ deamon Có nhưng tùy thuộc vào cách tiếp cận của nhà phát triển - Harshal Patil
@HarshalPatil Bạn có thể viết một ứng dụng với tất cả các logic nghiệp vụ trong các dịch vụ, nhưng điều đó sẽ dẫn đến một mô hình miền thiếu máu và nó sẽ làm cho nó không cần thiết để thực thi các ràng buộc và sự nhất quán trên các thực thể. - deamon


Spring 2.5 giới thiệu thêm các chú thích về khuôn mẫu: @Component, @Service và @Controller. @Component đóng vai trò như một khuôn mẫu chung cho bất kỳ thành phần được Spring quản lý nào; trong khi đó, @Repository, @Service và @Controller đóng vai trò là chuyên môn của @Component cho các trường hợp sử dụng cụ thể hơn (ví dụ: trong các lớp kiên trì, dịch vụ và bản trình bày tương ứng). Điều này có nghĩa là bạn có thể chú thích các lớp thành phần của bạn với @Component, nhưng bằng cách chú thích chúng bằng @Repository, @Service hoặc @Controller, các lớp của bạn phù hợp hơn để xử lý bằng các công cụ hoặc liên kết với các khía cạnh. Ví dụ: các chú thích định kiến ​​này tạo ra các mục tiêu lý tưởng cho các phím tắt. Tất nhiên, cũng có thể @Repository, @Service và @Controller có thể mang thêm ngữ nghĩa trong các phiên bản tương lai của Spring Framework. Do đó, nếu bạn đang đưa ra quyết định giữa việc sử dụng @Component hoặc @Service cho lớp dịch vụ của mình, @Service rõ ràng là lựa chọn tốt hơn. Tương tự, như đã nêu ở trên, @Repository đã được hỗ trợ làm điểm đánh dấu cho dịch ngoại lệ tự động trong lớp kiên trì của bạn.

@Component – Indicates a auto scan component.
@Repository – Indicates DAO component in the persistence layer.
@Service – Indicates a Service component in the business layer.
@Controller – Indicates a controller component in the presentation layer.

tài liệu tham khảo :- Tài liệu mùa xuân - Quét lớp đường dẫn, các thành phần được quản lý và các cấu hình bằng văn bản bằng cách sử dụng Java  


59
2018-05-15 12:48





@Component – Indicates a auto scan component.  
@Repository – Indicates DAO component in the persistence layer.  
@Service – Indicates a Service component in the business layer.   
@Controller – Indicates a controller component in the presentation layer.  

Bạn sẽ nhận thấy rằng tất cả @Repository,@Service hoặc là @Controller được chú thích bằng @Component. Vì vậy, chúng ta có thể sử dụng @Component cho tất cả các thành phần để quét tự động? Có, bạn có thể và Spring sẽ tự động quét tất cả các thành phần của bạn với chú thích @Component.

Nó hoạt động tốt, nhưng không phải là một thực hành tốt, để dễ đọc, bạn nên luôn khai báo @Repository,@Service hoặc là @Controller cho một lớp được chỉ định để làm cho mã của bạn dễ đọc hơn.


51
2017-12-16 18:10