2016-10-16 11 views
3

때문에 더 열심히 결합의 app-config.xml를 통해 구성하지 않고 있기 때문에 보안의 주석 스캔 기능과와없는 AppConfig.java,이 같은 봄 콩의 인스턴스를 만드는 데 :AppConfig.java 개인 생성자가있는 빈을 반환 하시겠습니까?

@Configuration 
public class AppConfig { 
    @Bean 
    public AddressService addressService(){ 
    return new AddressService(); 
    } 
} 

모든 것이 잘 작동하지만, 내가 무엇을 좋아하는 경우 다른 사람들이 인스턴스 AddressService을 만들지 못하도록하려면? 보통 나는 생성자를 private으로 선언 할 것이지만, 컴파일러는 AppConfig에있는 AddressService의 개인 생성자에 더 이상 액세스 할 수 없다는 오류를 준다! 완성도를 들어

, 이것은 AddressService입니다 :

public final class AddressService { 
    private AddressService(){} 
} 

답변

0

는 공용 인터페이스 및 민간 구현 클래스 패키지를 만듭니다. 수단 AddressingService은 공용 인터페이스이고 AddressingServiceImpl은 단지 @Service 주석이있는 개인용 패키지입니다. 이제 아무도 여러분의 Spring-Bean의 인스턴스를 생성 할 수 없으며 오직 하나의 인스턴스 만 Bean 범위에 기반하여 다른 인스턴스에 사용할 수있다. 빈을 @Autowired AddressingService으로 Autowire 할 수 있습니다.

AddressingServiceImpl이 동일한 패키지 내의 모든 클래스에서 직접 사용되는지 테스트하는 샘플 junit 테스트 케이스입니다.

이 경우 클래스는 src/main/java/com/address 패키지에 있습니다. 테스트 클래스는 src/test/java/com/address에 작성됩니다.

package com.address; 
import java.io.BufferedReader; 
import java.io.File; 
import java.io.FileReader; 
import java.util.Arrays; 
import org.junit.Test; 
import org.junit.*; 

public class BeansInitTest { 

@Test 
public void test() { 
    File[] files = new File("src/main/java/com/address").listFiles((File dir, String name) -> { 
     return name.endsWith(".java") && !name.equals(AddressServiceImpl.class.getSimpleName() + ".java"); 
    } 
    ); 

    Arrays.asList(files) 
      .stream().forEach(clazz -> checkInstanceCreation(clazz, AddressServiceImpl.class.getSimpleName())); 
} 

private void checkInstanceCreation(File clazz, String name) { 
    try (BufferedReader reader = new BufferedReader(new FileReader(clazz))){ 

     reader.lines().forEach(l -> { 
      Assert.assertFalse(l.contains(name)); 
     }); 

    }catch(Exception e){ 
     throw new RuntimeException(e); 
    } 
} 

}

이 그냥 샘플이며 필요에 따라 일반화 될 수 있습니다.

+0

왜 인터페이스입니까? 왜 constructor package-private을 선언하지 않는가? –

+0

사실, 무엇이 바뀌나요? OP는 주석 스캐닝을 사용할 수 없습니다 (선택하지 않음). 따라서 그는 여전히 "new AddressingService"를 수행 할 수 있어야합니다. 즉, 생성자가 다른 사람에게도 표시 될 수 있다는 의미입니까? – alexbt

+0

@Alex 생성자는 동일한 패키지에서 볼 수 있으며'package-private'은'default' 또는'protected'입니다. –

2

이것은 효과적인 해결책입니다.

@Configuration 
public class AppConfig { 
    public static class AddressService { 
     private AddressService() {} 
    } 
    @Bean 
    public AddressService addressService() { 
     return new AddressService(); 
    } 
}