Loại trừ các gói con khỏi tính năng tự động tạo Spring?


82

Có cách nào đơn giản để loại trừ một gói / gói con khỏi tính năng tự động tạo trong Spring 3.1 không?

Ví dụ: nếu tôi muốn bao gồm quét thành phần với gói cơ sở, com.examplecó cách nào đơn giản để loại trừ không com.example.ignore?

(Tại sao? Tôi muốn loại trừ một số thành phần khỏi các bài kiểm tra tích hợp của mình)

Câu trả lời:


84

Tôi không chắc bạn có thể loại trừ các gói một cách rõ ràng bằng <exclude-filter>, nhưng tôi cá rằng việc sử dụng bộ lọc regex sẽ đưa bạn đến đó một cách hiệu quả:

 <context:component-scan base-package="com.example">
    <context:exclude-filter type="regex" expression="com\.example\.ignore\..*"/>
 </context:component-scan>

Để làm cho nó dựa trên chú thích, bạn sẽ chú thích từng lớp mà bạn muốn loại trừ cho các bài kiểm tra tích hợp với một cái gì đó như @ com.example.annotation.ExcludedFromITests. Sau đó, quét thành phần sẽ giống như sau:

 <context:component-scan base-package="com.example">
    <context:exclude-filter type="annotation" expression="com.example.annotation.ExcludedFromITests"/>
 </context:component-scan>

Điều đó rõ ràng hơn vì bây giờ bạn đã ghi lại trong chính mã nguồn rằng lớp không được dự định đưa vào ngữ cảnh ứng dụng cho các bài kiểm tra tích hợp.


Sử dụng bộ lọc loại trừ hoạt động nhưng tôi không phải thoát "."
Amin

2
@Amin Đó có thể là bởi vì "." tính cho bất kỳ ký tự nào bao gồm cả chữ "."
aksh1618

54

Tôi đang sử dụng @ComponentScannhư sau cho cùng một trường hợp sử dụng. Câu trả lời này giống với câu trả lời XML của BenSchro10 nhưng điều này sử dụng chú thích. Cả hai đều sử dụng bộ lọc vớitype=AspectJ

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration;
import org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration;
import org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.FilterType;
import org.springframework.context.annotation.ImportResource;

@SpringBootApplication
@EnableAutoConfiguration
@ComponentScan(basePackages = { "com.example" },
    excludeFilters = @ComponentScan.Filter(type = FilterType.ASPECTJ, pattern = "com.example.ignore.*"))
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Có thể đó hoàn toàn là hoài niệm, nhưng tôi thực sự vẫn thích XML hơn
Kirby

10
nó có thể là tôi, nhưng với mùa xuân 4,2 tôi phải sử dụng FilterType.REGEXcho phương pháp này
ThanksForAllTheFish

Đây là những gì tôi muốn, nhưng tôi cũng phải sử dụng FilterType.REGEX. Có lẽ câu trả lời có thể được cập nhật để phản ánh điều này?
Adam

1
Hãy thoải mái đưa ra câu trả lời mới
Kirby

37

Đối với Spring 4, tôi sử dụng như sau
(tôi đăng nó vì câu hỏi là 4 tuổi và nhiều người sử dụng Spring 4 hơn Spring 3.1):

@Configuration
@ComponentScan(basePackages = "com.example", 
  excludeFilters = @Filter(type=FilterType.REGEX,pattern="com\\.example\\.ignore\\..*")) 
public class RootConfig {
    // ...
}

13

Có vẻ như bạn đã thực hiện điều này thông qua XML, nhưng nếu bạn đang làm việc trong phương pháp hay nhất của Spring mới, thì cấu hình của bạn sẽ bằng Java và bạn có thể loại trừ chúng như vậy:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "net.example.tool",
  excludeFilters = {@ComponentScan.Filter(
    type = FilterType.ASSIGNABLE_TYPE,
    value = {JPAConfiguration.class, SecurityConfig.class})
  })

9
@JonathanW Nhưng tuy nhiên, một câu trả lời thực sự hữu ích cho những người đến trang này từ một tìm kiếm google
Stewart

12

Điều này hoạt động trong Spring 3.0.5. Vì vậy, tôi nghĩ rằng nó sẽ hoạt động trong 3.1

<context:component-scan base-package="com.example">  
    <context:exclude-filter type="aspectj" expression="com.example.dontscanme.*" />  
</context:component-scan> 

1
Lưu ý rằng nó âm thầm bỏ qua loại trừ trong trường hợp khía cạnhj không có trên classpath.
Vadzim

7

Tôi nghĩ bạn nên cấu trúc lại các gói của mình theo hệ thống phân cấp thuận tiện hơn, vì vậy chúng nằm ngoài gói cơ sở.

Nhưng nếu bạn không thể làm điều này, hãy thử:

<context:component-scan base-package="com.example">
    ...
    <context:exclude-filter type="regex" expression="com\.example\.ignore.*"/>
</context:component-scan>

Tại đây, bạn có thể tìm thấy thêm các ví dụ: Sử dụng bộ lọc để tùy chỉnh quét


Cảm ơn, về nguyên tắc, tôi đồng ý với ý tưởng tái cấu trúc - đó là suy nghĩ đầu tiên của tôi. Thật không may, nó không thực sự là một lựa chọn tuyệt vời cho tình huống cụ thể của tôi.
HolySamosa

Thiết kế bao bì tốt có thể tránh được tình huống này, nhưng nếu bạn không thể ... bạn có thể không hahaha, :)
richarbernal

4

Một điều có vẻ hiệu quả với tôi là:

@ComponentScan(basePackageClasses = {SomeTypeInYourPackage.class}, resourcePattern = "*.class")

Hoặc trong XML:

<context:component-scan base-package="com.example" resource-pattern="*.class"/>

Điều này ghi đè mặc định resourcePattern"**/*.class".

Đây có vẻ là cách an toàn nhất để CHỈ đưa vào gói cơ sở của bạn vì resourcePattern đó sẽ luôn giống nhau và có liên quan đến gói cơ sở của bạn.


2

Bạn cũng có thể sử dụng @SpringBootApplication , theo tài liệu Spring thực hiện chức năng tương tự như ba chú thích sau: @Configuration , @EnableAutoConfiguration @ComponentScan trong một chú thích.

@SpringBootApplication(exclude= {Foo.class})
public class MySpringConfiguration {}

Theo Javadoc, excludeLoại trừ các lớp cấu hình tự động cụ thể , không phải tất cả các lớp khỏi quét thành phần. Nếu cố gắng, bạn sẽ gặp lỗi " Không thể loại trừ các lớp sau vì chúng không phải là các lớp cấu hình tự động ".
Abhijit Sarkar

0

Bạn cũng có thể bao gồm gói cụ thể và loại trừ chúng như:

Bao gồm và loại trừ (cả hai)

 @SpringBootApplication
        (
                scanBasePackages = {
                        "com.package1",
                        "com.package2"
                },
                exclude = {org.springframework.boot.sample.class}
        )

CHỈ Loại trừ

@SpringBootApplication(exclude= {com.package1.class})
public class MySpringConfiguration {}

Theo Javadoc, excludeLoại trừ các lớp cấu hình tự động cụ thể , không phải tất cả các lớp khỏi quét thành phần. Nếu cố gắng, bạn sẽ gặp lỗi " Không thể loại trừ các lớp sau vì chúng không phải là các lớp cấu hình tự động ".
Abhijit Sarkar
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.