莫方教程网

专业程序员编程教程与实战案例分享

JAVA面试|Spring原理

一、Spring 框架的核心原理

Spring 框架的核心思想是控制反转(IoC)和面向切面编程(AOP),通过模块化设计和扩展性支持企业级应用开发。以下是其核心原理的详细分析。


二、控制反转(IoC)和依赖注入(DI)

1. 通俗解释

想象你是一个餐馆老板。传统方式是你自己买菜、炒菜、端菜(代码直接new对象)。而用了Spring后,你只需要告诉服务员“我要一份牛排”(声明需要什么对象),服务员(Spring容器)会把做好的牛排送到你面前。这就是控制反转(你不用自己“控制”对象的创建)。

2. 代码示例

假设有一个“用户服务”(UserService),需要依赖“用户仓库”(UserRepository)操作数据库。

(1) 传统写法(自己控制对象)

public class UserService {

private UserRepository userRepository = new UserRepository(); // 直接 new 对象

public void saveUser() {

userRepository.save();

}

}

(2) Spring 写法(依赖注入)

@Component // 告诉 Spring:这个类需要被管理

public class UserService {

@Autowired // 告诉 Spring:请自动注入一个 UserRepository

private UserRepository userRepository;


public void saveUser() {

userRepository.save();

}

}


@Component // 告诉 Spring:这个类也要被管理

public class UserRepository {

public void save() {

System.out.println("保存用户到数据库");

}

}

(3) 运行代码

public class Main {

public static void main(String[] args) {

// 1. 启动 Spring 容器(自动扫描带 @Component 的类)

ApplicationContext context = new AnnotationConfigApplicationContext("com.example");


// 2. 从容器中获取 UserService(不用自己 new)

UserService userService = context.getBean(UserService.class);


// 3. 调用方法

userService.saveUser(); // 输出:保存用户到数据库

}

}

3. 关键点

(1)Spring 容器会扫描 @Component 注解的类,并自动创建它们的对象(称为 Bean)。

(2)@Autowired 让 Spring 自动把 UserRepository 对象注入到 UserService 中(类似“服务员递给你牛排”)。


三、面向切面编程(AOP)

1. 通俗解释

假设你在写一个游戏,每个关卡开始和结束时需要记录日志。传统方式是在每个关卡代码里写日志逻辑,但这样代码会重复。AOP允许你把这些重复的逻辑(比如日志、事务)抽出来,像“切面”一样插入到需要的地方。

2. 代码示例

(1) 业务代码

@Service

public class GameService {

public void startLevel(int level) {

System.out.println("第 " + level + " 关开始!");

}


public void endLevel(int level) {

System.out.println("第 " + level + " 关结束!");

}

}

(2) 日志切面

@Aspect // 声明这是一个切面

@Component

public class LogAspect {

// 定义切点:拦截所有 GameService 的方法

@Pointcut("execution(* com.example.GameService.*(..))")

public void gameServiceMethods() {}


// 前置通知:在方法执行前执行

@Before("gameServiceMethods()")

public void logBefore(JoinPoint joinPoint) {

String methodName = joinPoint.getSignature().getName();

System.out.println("方法执行前:" + methodName);

}


// 后置通知:在方法执行后执行

@After("gameServiceMethods()")

public void logAfter(JoinPoint joinPoint) {

String methodName = joinPoint.getSignature().getName();

System.out.println("方法执行后:" + methodName);

}

}

(3) 运行代码

public class Main {

public static void main(String[] args) {

ApplicationContext context = new AnnotationConfigApplicationContext("com.example");

GameService gameService = context.getBean(GameService.class);

gameService.startLevel(1);

gameService.endLevel(1);

}

}

(4) 输出

方法执行前:startLevel

第 1 关开始!

方法执行后:startLevel

方法执行前:endLevel

第 1 关结束!

方法执行后:endLevel

3. 关键点

(1)切面(Aspect):把日志逻辑单独抽出来,不混在业务代码里。

(2)动态代理:Spring 会在运行时为 GameService 生成一个代理对象,在方法调用前后插入日志逻辑。


四、Spring 容器的核心流程

1. 步骤

(1)启动容器:就像打开一个工具箱,Spring会扫描所有带 @Component的类。

(2)创建 Bean:把每个类实例化成对象(单例模式,默认只创建一个)。

(3)依赖注入:检查哪些Bean需要其他Bean(比如 @Autowired),自动“装配”进去。

(4)AOP 处理:如果有切面,生成代理对象,插入额外逻辑。

(5)提供 Bean:当你从容器中获取对象时,它已经是组装好的完整对象。

2. 代码模拟 Spring 的简化版 IoC 容器

public class SimpleContainer {

private Map<String, Object> beans = new HashMap<>();


// 扫描并创建所有 Bean

public void init() {

// 1. 创建 UserRepository

UserRepository userRepository = new UserRepository();

beans.put("userRepository", userRepository);


// 2. 创建 UserService 并注入 UserRepository

UserService userService = new UserService();


userService.setUserRepository(userRepository); // 手动注入依赖

beans.put("userService", userService);

}


// 从容器中获取 Bean

public <T> T getBean(Class<T> clazz) {

return (T) beans.values().stream()

.filter(clazz::isInstance)

.findFirst()

.orElse(null);

}

}

3. 使用方式

public class Main {

public static void main(String[] args) {

SimpleContainer container = new SimpleContainer();

container.init(); // 初始化容器

UserService userService = container.getBean(UserService.class);

userService.saveUser(); // 输出:保存用户到数据库

}

}


五、总结

(1) IoC 容器:帮你管理对象的创建和依赖关系,不用自己new。

(2) 依赖注入:通过 @Autowired 自动装配对象。

(3) AOP:通过动态代理,把日志、事务等逻辑像“切片”一样插入到代码中。

(4) Spring 就像你的私人助手:你只需要告诉它你需要什么(@Component 和 @Autowired),它会自动帮你搞定对象的创建、组装和增强!

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言

    滇ICP备2024046894号-1