深入解析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的默认规则与修改方式。

相关推荐
CoderYanger1 小时前
动态规划算法-子序列问题(数组中不连续的一段):28.摆动序列
java·算法·leetcode·动态规划·1024程序员节
Mai Dang1 小时前
SpringBoot4用Swagger
java
expect7g2 小时前
Paimon源码解读 -- Compaction-2.KeyValueFileWriterFactory
大数据·后端·flink
小灰灰搞电子2 小时前
Rust 动态分发(dyn Trait)详解
开发语言·后端·rust
码事漫谈2 小时前
深入剖析进程、线程与虚拟内存
后端
码事漫谈2 小时前
MFC核心架构深度解析
后端
geekmice2 小时前
实现一个功能:springboot项目启动将controller地址拼接打印到txt文件
java·spring boot·后端
老华带你飞2 小时前
旅游|基于Java旅游信息系统(源码+数据库+文档)
java·开发语言·数据库·vue.js·spring boot·旅游