Container Architecture Fundamentals
public class CustomApplicationContext {
private Class configurationClass;
private Map<String, BeanDefinition> definitionRegistry = new ConcurrentHashMap<>();
private Map<String, Object> singletonCache = new ConcurrentHashMap<>();
public CustomApplicationContext(Class configClass) {
this.configurationClass = configClass;
initializeContainer();
}
public Object getBean(String beanId) {
BeanDefinition definition = definitionRegistry.get(beanId);
if (definition == null) throw new IllegalArgumentException("Undefined bean: " + beanId);
if ("singleton".equals(definition.getScope())) {
return singletonCache.computeIfAbsent(beanId,
k -> createBeanInstance(definition));
}
return createBeanInstance(definition);
}
}
Container Initialziation
public class MainApp {
public static void main(String[] args) {
CustomApplicationContext ctx =
new CustomApplicationContext(ApplicationConfig.class);
UserService service = (UserService) ctx.getBean("userService");
}
}
Core Annotation Definitions
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ComponentScan {
String basePackages() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Component {
String identifier() default "";
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Scope {
String value() default "singleton";
}
Configuration and Metadtaa
@ComponentScan(basePackages = "com.example.services")
public class ApplicationConfig {}
public class BeanDefinition {
private Class beanClass;
private String lifecycle;
// Getters and setters
}
Initialization Process
private void initializeContainer() {
ComponentScan scanConfig = (ComponentScan) configurationClass.getAnnotation(ComponentScan.class);
String packagePath = scanConfig.basePackages().replace(".", "/");
URL resource = getClass().getClassLoader().getResource(packagePath);
File directory = new File(resource.getFile());
Arrays.stream(directory.listFiles())
.filter(f -> f.getName().endsWith(".class"))
.forEach(f -> registerComponent(f));
instantiateSingletons();
}
private void registerComponent(File classFile) {
String absolutePath = classFile.getAbsolutePath();
String className = absolutePath.substring(absolutePath.indexOf("com"), absolutePath.indexOf(".class"))
.replace(File.separator, ".");
try {
Class> clazz = Class.forName(className);
if (clazz.isAnnotationPresent(Component.class)) {
Component comp = clazz.getAnnotation(Component.class);
BeanDefinition def = new BeanDefinition();
def.setBeanClass(clazz);
def.setLifecycle(clazz.isAnnotationPresent(Scope.class) ?
clazz.getAnnotation(Scope.class).value() : "singleton");
definitionRegistry.put(comp.identifier(), def);
}
} catch (Exception e) { /* Error handling */ }
}
private void instantiateSingletons() {
definitionRegistry.entrySet().stream()
.filter(entry -> "singleton".equals(entry.getValue().getLifecycle()))
.forEach(entry -> singletonCache.put(entry.getKey(),
createBeanInstance(entry.getValue())));
}
private Object createBeanInstance(BeanDefinition definition) {
try {
return definition.getBeanClass().getDeclaredConstructor().newInstance();
} catch (Exception e) {
throw new RuntimeException("Bean instantiation failure", e);
}
}