深入解析Spring IoC核心与关键注解

Spring IoC 的核心

IoC 是 Spring 的核心思想之一,核心是「将对象的创建、管理(依赖、生命周期)交给 Spring 容器(ApplicationContext),而不是由开发者手动 new 对象」------ 也就是 "反转控制"(把对象创建的控制权从开发者手里转给 Spring)。

Spring 容器会扫描特定注解(如 @Controller@Service@Component 等)标记的类,自动创建它们的实例(这些实例叫Bean),并存储在容器中;开发者后续需要使用对象时,直接从容器中 "获取"(getBean)即可,无需手动创建。

代码示例

HelloController类:(把对象交给 Spring 管理)

java 复制代码
@Controller //这个注解就把这个HelloController这个对象交给了Spring来进行管理
public class HelloController {
    public void print(){
        System.out.println("do Controller");
    }
}

DemoApplication类:Bean 的获取(从 Spring 容器拿对象)

java 复制代码
@SpringBootApplication //一个类有这个注解就表明这个类是启动类 不管类名是什么
public class DemoApplication {

	public static void main(String[] args) {

        // 1. 启动 Spring 应用,创建 Spring 容器(ApplicationContext)
		// 容器启动时,会扫描到 @Controller 标记的 HelloController,自动创建其 Bean
		ApplicationContext context = SpringApplication.run(DemoApplication.class, args);

		// 2. 三种从容器中获取对象的方式:
		HelloController bean= (HelloController) context.getBean("helloController"); 
        //按Bean名称获取(需强转)
		bean.print();

		HelloController bean2=context.getBean(HelloController.class);
        //按Bean类型获取(无需强转)
		bean2.print();

		HelloController bean3=context.getBean("helloController",HelloController.class);
        //按 名称+类型 的方式获取
    	bean3.print();

		System.out.println(bean);
		System.out.println(bean2);
		System.out.println(bean3);
	}

}

运行结果如下:

从运行结果可以看到,三次调用print方法都输出了 "do Controller";而三个对象的打印结果完全一致(内存地址都是@33063f5b)。

这恰恰印证了一个关键特性:尽管我们用了三种不同的方式从 Spring 容器中获取 HelloController对象,但最终拿到的其实是同一个实例。

其他四大注解

@Service

java 复制代码
@Service
public class UserService {
    public void print(){
        System.out.println("do Service");
    }
}
java 复制代码
        UserService bean4 =context.getBean(UserService.class);
		bean4.print();

运行结果如下:

@Repository

java 复制代码
@Repository
public class UserRepository {
    public void print(){
        System.out.println("do Repository");
    }
}

@Configuration

java 复制代码
@Configuration
public class UserConfig {
    public void print(){
        System.out.println("do Config");
    }
}

@Component

java 复制代码
@Component
public class UserComponent {
    public void print(){
        System.out.println("do Component");
    }
}

由上述代码示例可见,这五个注解的用法都是差不多的。那么他们之间有什么联系和区别呢?

五大注解的联系和区别

复制代码
@Controller通常用在控制层(接收参数,返回响应)
@Service通常用在业务逻辑层
@Repository通常用在数据层
@Configuration通常用在配置层
@Component通常用在组建层

@Bean

需要注意的是@Bean注解需要结合前面所学的五大注解进行使用:

java 复制代码
@Component 
public class StudentComponent {
@Bean
    public Student s1(){
        return new Student("zhangsan",18);
    }
}
java 复制代码
Student bean9=(Student) context.getBean("s1");
		System.out.println(bean9);

由此可见,这个BeanName默认是方法名,除此之外我们也可以对它来进行重命名:

java 复制代码
@Bean("s3")
    public Student s1(){
        return new Student("zhangsan",18);
    }
java 复制代码
Student bean9=(Student) context.getBean("s3");
		System.out.println(bean9);

五大注解和@Bean的BeanName

五大注解的BeanName默认是类名的小驼峰写法,如果类名的前两个字母都是大写,那么BeanName就是类名本身;

@Bean则需要搭配五大注解来使用,BeanName默认是方法名。

二者的BeanName均可以修改

结语

本文我们梳理了Spring IoC的核心思想,了解了其通过反转控制将对象创建与管理交给Spring容器的逻辑,也通过具体代码示例掌握了Bean的获取方式。同时,剖析了五大注解(@Controller、@Service、@Repository、@Configuration、@Component)的用法、分层场景差异,以及@Bean注解的使用规则,也明确了各类注解BeanName的默认规则与修改方式。

相关推荐
Tony Bai20 小时前
Go 语言的“魔法”时刻:如何用 -toolexec 实现零侵入式自动插桩?
开发语言·后端·golang
未若君雅裁20 小时前
SpringAI基础入门
java·spring boot·ai
CC.GG20 小时前
【C++】用哈希表封装myunordered_map和 myunordered_set
java·c++·散列表
a努力。21 小时前
字节Java面试被问:TCP的BBR拥塞控制算法原理
java·开发语言·python·tcp/ip·elasticsearch·面试·职场和发展
jiaguangqingpanda21 小时前
Day24-20260120
java·开发语言·数据结构
一个龙的传说21 小时前
xshell下载
java
C雨后彩虹21 小时前
羊、狼、农夫过河
java·数据结构·算法·华为·面试
java资料站21 小时前
SpringAI+DeepSeek大模型应用开发实战
java
进击的CJR1 天前
redis cluster 部署
java·redis·mybatis
重生之后端学习1 天前
19. 删除链表的倒数第 N 个结点
java·数据结构·算法·leetcode·职场和发展