2016-10-16 11 views
3

があるため難しく結合のapp-config.xmlを介したコンフィギュレーションのないため、セキュリティの注釈スキャンととせずにAppConfig.java、私はこのような春豆のインスタンスを作成した:AppConfig.javaプライベートコンストラクタを持つBeanを返しますか?

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

すべてが素晴らしい作品が、私は何が好きなら他人がインスタンスAddressServiceを作成しないようにするには?通常私はコンストラクタをプライベート宣言しますが、コンパイラは私にAppConfigAddressServiceの専用コンストラクタにアクセスできなくなるというエラーを返します!完全のために

、これはAddressServiceです:

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

答えて

0

は、パブリックインターフェイスとプライベート実装クラスのパッケージを作成します。手段AddressingServiceはパブリックインターフェイスであり、AddressingServiceImplは単なるパッケージプライベートで、@Service注釈です。誰もあなたのSpring-Beanのインスタンスを作成することはできず、Beanのスコープに基づいて他のインスタンスに対して利用できるインスタンスは1つだけです。あなたは@Autowired AddressingServiceとしてBeanを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

なぜインターフェイスですか?コンストラクタをpackage-privateと宣言してみませんか? –

+0

実際、何が変わるのですか? OPはアノテーションスキャンを使用できない(選択しない)ことができます。だから彼はまだ "新しい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(); 
    } 
} 
関連する問題