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

相关推荐
葫芦和十三3 小时前
图解 MongoDB 21|选举与 failover:Primary 是怎么选出来的
后端·mongodb·agent
GetcharZp4 小时前
26k Star 开源内网穿透神器 NetBird,一分钟实现全球设备互联!
后端
考虑考虑4 小时前
Mybatis实现批量插入
java·后端·mybatis
咖啡八杯5 小时前
GoF设计模式——中介者模式
java·后端·spring·设计模式
lizhongxuan7 小时前
多Agent之间的区别
后端
青石路9 小时前
记一次多JDK版本问题的排查,一坑套一坑,差点没爬上来
java
杨充9 小时前
1.面向对象设计思想
后端
IT_陈寒10 小时前
Java的Date类又坑了我一次,改用时间戳真香
前端·人工智能·后端
systemPro10 小时前
2.6亿条设备数据,历史查询从超时到50ms,我做了什么
后端
要阿尔卑斯吗10 小时前
提示词优化启示:为什么“按顺序输出“比“关键度评分“更有效
后端