클래스에 인스턴스가 하나만 있도록 하면서 인스턴스에 대한 액세스 지점을 제공하는 패턴
class Database {
private static volatile Database instance;
private Database() {
System.out.println("Connecting to the database...");
}
public static Database getInstance() {
if (instance == null) {
synchronized (Database.class) {
if (instance == null) {
instance = new Database();
}
}
}
return instance;
}
public void query(String sql) {
System.out.println("Executing query: " + sql);
}
}
public class Application {
public static void main(String[] args) {
Database foo = Database.getInstance();
foo.query("SELECT * FROM users");
Database bar = Database.getInstance();
bar.query("SELECT * FROM products");
System.out.println("foo == bar: " + (foo == bar));
}
}
class ConfigManager {
private static ConfigManager instance;
private Map<String, String> configData;
private ConfigManager() {
configData = new HashMap<>();
configData.put("db_url", "jdbc:mysql://localhost:3306/mydb");
configData.put("api_key", "12345-ABCDE");
}
public static ConfigManager getInstance() {
if (instance == null) {
instance = new ConfigManager();
}
return instance;
}
public String getConfig(String key) {
return configData.get(key);
}
}
class DatabaseConnection {
public void connect() {
String dbUrl = ConfigManager.getInstance().getConfig("db_url");
System.out.println("Connecting to: " + dbUrl);
}
}
class ApiService {
public void callApi() {
String apiKey = ConfigManager.getInstance().getConfig("api_key");
System.out.println("Calling API with key: " + apiKey);
}
}
public class Main {
public static void main(String[] args) {
DatabaseConnection dbConnection = new DatabaseConnection();
dbConnection.connect();
ApiService apiService = new ApiService();
apiService.callApi();
}
}
특징 | Singleton | Spring Bean |
---|---|---|
관리 주체 | 클래스 자체 | Spring 컨테이너 |
스코프 | 항상 단일 인스턴스 | 기본 Singleton, 다른 스코프 가능 |
의존성 주입 | 지원하지 않음 | DI 지원 (유연하고 테스트 친화적) |
스레드 안전성 | 직접 구현 필요 | Spring이 관리 가능 |
테스트 용이성 | 낮음 | 높음 |
확장성 및 유연성 | 낮음 | 높음 |