4

由于AppConfig.java安全性而没有注释扫描,并且app-config.xml由于更难绑定而没有配置,我创建了这样的 spring-beans 实例:

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

一切都很好,但是如果我想阻止其他人创建 InstanceAddressService怎么办?通常我会将构造函数声明为私有,但编译器给了我一个错误,我无法再访问私有构造函数 AddressServiceAppConfig

为了完整起见,这是AddressService

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

2 回答 2

4

这是一个可行的解决方案。

@Configuration
public class AppConfig {
    public static class AddressService {
        private AddressService() {}
    }
    @Bean
    public AddressService addressService() {
        return new AddressService();
    }
}
于 2016-10-16T12:06:24.597 回答
0

创建一个公共接口和私有的实现类包。手段AddressingService是公共接口,AddressingServiceImpl只是带有@Service注释的私有包。现在没有人能够创建您的 spring-bean 的实例,并且根据您的 bean 范围,只有一个实例可供其他人使用。您可以将 bean 自动装配为@Autowired AddressingService.

一个示例 junit 测试用例,用于测试是否AddressingServiceImpl直接在同一包内的任何类中使用。

在这种情况下,这些类位于 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);
    }
}

}

请注意,这只是一个示例,可以根据需要进行概括。

于 2016-10-16T11:38:07.823 回答