Master Spring Framework: From Basics to AOP, DI, and Dynamic Proxies
This comprehensive guide walks you through Spring's core concepts—including IOC, DI, bean lifecycle, static and dynamic proxy patterns, AOP with annotations, and essential Spring annotations—while providing clear Java code examples and practical use‑cases for backend development.
Why Use Spring?
Spring simplifies object management by handling bean creation, dependency injection, and aspect‑oriented programming, reducing boilerplate code and improving decoupling.
1. Spring Overview
Spring is a lightweight Java framework whose core features are Inversion of Control (IOC) and Aspect‑Oriented Programming (AOP).
1.1 IOC (Inversion of Control)
IOC transfers object creation and dependency management from the program to the Spring container.
1.2 DI (Dependency Injection)
DI is the concrete implementation of IOC; Spring injects required dependencies via setter or constructor methods.
2. Bean Lifecycle
Spring beans go through three stages: creation, initialization, and destruction.
2.1 Creation
Beans can be created as singleton (default) or prototype . The lazy-init="true" attribute delays creation until first use.
2.2 Initialization
Initialization can be defined by implementing InitializingBean, specifying an init-method in XML, or using @PostConstruct.
2.3 Destruction
Destruction can be handled by implementing DisposableBean, defining a destroy-method, or using @PreDestroy.
3. Bean Post‑Processing
Implement BeanPostProcessor to modify beans after creation, e.g., setting default values or logging.
4. Proxy Design Patterns
Static proxy requires a separate proxy class for each target, leading to code duplication. Dynamic proxy creates proxies at runtime, eliminating manual proxy classes.
4.1 JDK Dynamic Proxy
Works for interfaces. Use Proxy.newProxyInstance with a class loader, interfaces, and an InvocationHandler that adds extra behavior.
Proxy.newProxyInstance(classLoader, interfaces, invocationHandler)4.2 CGLIB Dynamic Proxy
Works for concrete classes by subclassing them. Use Enhancer to set the superclass and a MethodInterceptor.
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(TargetClass.class);
enhancer.setCallback(interceptor);
Object proxy = enhancer.create();5. AOP (Aspect‑Oriented Programming)
AOP adds cross‑cutting concerns (e.g., logging) without modifying business code. A pointcut defines where the aspect applies, and advice defines the extra behavior.
5.1 Pointcut Expressions
Typical expression: execution(* com.example.service.*.*(..)) matches all methods in the specified package.
5.2 Advice Types
@Before: runs before the target method. @After: runs after the target method. @Around: wraps the target method, allowing code before and after execution.
5.3 Annotation‑Based AOP Example
@Aspect
public class LogAspect {
@Around("execution(* *(..))")
public Object log(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("Before method");
Object result = joinPoint.proceed();
System.out.println("After method");
return result;
}
}6. Spring Annotations for Bean Creation
@Component: generic stereotype for any Spring‑managed component. @Controller, @Service, @Repository: specialized stereotypes for MVC, service, and DAO layers. @Scope("prototype"): defines prototype‑scoped beans. @PostConstruct / @PreDestroy: lifecycle callbacks replacing XML init-method and destroy-method.
7. Dependency Injection Annotations
@Autowired: type‑based injection (can combine with @Qualifier for name‑based injection). @Resource: name‑based injection defined by JSR‑250.
8. Java‑Based Configuration
Replace XML with Java classes: @Configuration: marks a class as a source of bean definitions. @Bean: defines a bean method; the method name becomes the bean ID unless overridden. @ComponentScan: scans specified packages for @Component and related stereotypes.
9. Practical Example
A User class is annotated with @Component and injects a Product bean via @Autowired. The Product bean is defined either with @Component or with a @Bean method in a configuration class. Lifecycle methods are demonstrated with @PostConstruct.
@Component
public class User {
private String name;
@Autowired
private Product product;
@PostConstruct
public void init() { this.name = "John"; }
// getters, setters, toString()
}
@Component
public class Product {
private String productName;
// getters, setters, toString()
}
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
@Bean
public Product product() {
Product p = new Product();
p.setProductName("Apple");
return p;
}
}Running the application with AnnotationConfigApplicationContext(AppConfig.class) retrieves the User bean, which already has the Product injected and the name initialized.
10. Visual Aids
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java High-Performance Architecture
Sharing Java development articles and resources, including SSM architecture and the Spring ecosystem (Spring Boot, Spring Cloud, MyBatis, Dubbo, Docker), Zookeeper, Redis, architecture design, microservices, message queues, Git, etc.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
