大家好这里是苏泽,一个从小喜欢钻研原理的疯小子 这篇文章是我的专栏《Spring 狂野之旅:底层原理高级进阶》 🚀 的第一篇文章 也是学习写一个讲解底层原理的博客的第一课 我认为深入了解一个事物的全貌是一件神秘而刺激的过程 希望你们能和我一样Enjoy the process 这个专栏里我希望能把Spring的底层原理讲得彻彻底底 让普通人也能一看就懂的程度 会慢慢更新 如果有想法可以在评论区提哦 相互交流学习的小伙伴可以关注一下我 技术博客每日一更
下面正式开始基本认识Sprin
在软件开发的世界里,有一种魔法可以让我们的代码更加灵活、解耦,它就是IoC(控制反转)。今天,让我们一起揭开IoC的神秘面纱,看看它是如何让我们的代码像呼吸一样自然。
想象一下,如果你是一名厨师,每当你需要煮一壶水时,都必须亲自去河边打水,然后生火,最后才能煮水。这样不仅效率低下,而且极其繁琐。如果有人能帮你准备好水,甚至帮你煮好水,那该多好啊!
这就是IoC的精髓所在。在没有IoC的传统开发模式中,对象自己控制着自己的行为。而一旦引入IoC,对象的创建和生命周期的控制就被反转了,交给了外部一个容器来管理。这就好比你不再需要亲自去河边打水,而是有一个“厨房助手”来帮你准备好一切。
// 传统方式,对象自己控制一切
public class TraditionalService {
private Dependency dependency = new Dependency();
public void doSomething() {
dependency.doWork();
}
}
// 使用IoC后,对象的创建被反转,由外部控制
public class IoCService {
private Dependency dependency;
// 依赖通过构造器注入,由外部(如IoC容器)控制
public IoCService(Dependency dependency) {
this.dependency = dependency;
}
public void doSomething() {
dependency.doWork();
}
}
在Java世界中,IoC最常见的实现方式有两种:依赖注入(DI)和面向切面编程(AOP)。
依赖注入是IoC的一种实现方式,它通过“注入”依赖对象来减少对象间的耦合。依赖可以通过构造器、setter方法或者字段直接注入。
@Component
public class UserService {
private final UserRepository userRepository;
@Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository; // 依赖注入
}
}
AOP则是另一种IoC的体现,它允许我们对程序进行横向切割,将一些跨越应用程序多个部分的关注点(如日志、事务管理)模块化到独立的切面中。
@Aspect
@Component
public class LoggingAspect {
@Before("execution(* com.example.service.*.*(..))")
public void logBeforeServiceMethod(JoinPoint joinPoint) {
System.out.println("Before executing: " + joinPoint.getSignature().getName());
}
}
IoC容器是IoC实现的核心,它负责实例化、配置和组装对象。Spring框架提供了强大的IoC容器,主要分为两种类型:BeanFactory和ApplicationContext。
BeanFactory是Spring框架中的基础设施,支持依赖注入(DI),它管理Bean的定义并使用依赖注入(DI)原则组装它们。
XmlBeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));
MyBean bean = (MyBean) factory.getBean("myBean");
ApplicationContext是BeanFactory的子接口,提供了更多高级特性,如消息国际化、事件发布等。它是使用Spring IoC容器的首选方式。
ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
MyBean bean = context.getBean(MyBean.class);
在Spring框架的世界里,Bean是构成应用程序骨架的基础元素。它们如同细胞一样,承载着数据和行为,构建出复杂而强大的生命体——我们的应用程序。今天,我们将深入探讨Bean的定义、生命周期,以及它们的作用和分类。
在Spring框架中,Bean是由Spring IoC容器管理的对象。这些对象不需要通过new关键字实例化,而是由Spring容器负责实例化、配置和组装。
@Component
public class ExampleBean {
// Bean的内容
}
了解Bean的生命周期对于编写高效、可维护的Spring应用至关重要。Bean的生命周期包括以下几个阶段:
@Service
public class MyService {
// 业务逻辑
}
@Repository
public class MyRepository {
// 数据访问逻辑
}
@Controller
public class MyController {
// 处理Web请求
}
Spring Bean承担着各种角色,从简单的配置对象,到处理Web请求的控制器,再到处理业务逻辑的服务类。Bean的主要作用包括:
根据Bean的作用和行为,我们可以将其分为几类:
@Service
public class MyService {
// 业务逻辑
}
@Repository
public class MyRepository {
// 数据访问逻辑
}
@Controller
public class MyController {
// 处理Web请求
}
Spring Bean是Spring框架的核心,它不仅仅是简单的数据容器,更是承载了Spring应用复杂逻辑和功能的基石。通过深入理解Bean的定义、生命周期以及分类,我们可以更加有效地利用Spring框架构建出健壮、灵活且易于维护的应用程序。
在Spring的世界里,配置是构建和维护应用程序的关键。随着Spring框架的发展,配置方式也从最初的XML配置演变到了注解和JavaConfig。每种配置方式都有其独特的特点和适用场景。今天,我们将深入探讨这些配置方式,帮助你选择最适合你项目的配置方法。
在Spring的早期版本中,XML配置是主流的配置方式。通过XML文件,开发者可以定义Bean以及Bean之间的依赖关系。
<beans>
<bean id="myBean" class="com.example.MyBean">
<property name="dependency" ref="myDependency"/>
</bean>
<bean id="myDependency" class="com.example.MyDependency"/>
</beans>
随着Spring 2.5的发布,注解配置开始成为主流。它通过在类、字段或方法上添加注解来实现Bean的声明和依赖注入。
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean(myDependency());
}
@Bean
public MyDependency myDependency() {
return new MyDependency();
}
}
JavaConfig是一种基于Java的配置方式,它允许开发者通过编写配置类来实现Bean的定义和依赖注入。
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean(myDependency());
}
@Bean
public MyDependency myDependency() {
return new MyDependency();
}
}
注解和JavaConfig不仅仅是配置Spring应用的方式,它们代表了一种现代化的、与代码紧密集成的配置思想。通过合理利用这些特性,我们可以构建出更加灵活、易于维护的应用。
@ComponentScan
注解自动扫描并注册Bean。@Autowired
注解实现自动依赖注入。@Qualifier
注解解决自动装配时的歧义性。@Profile
注解定义不同环境下的配置。@Configuration
注解标记。@Bean
注解方法,返回Bean的实例。@Profile
和@Conditional
注解实现条件化的Bean创建。在Spring框架中,理解Bean的作用域和生命周期是至关重要的,它们决定了Bean的创建、管理及销毁方式。本篇博客将深入探讨这两个概念,并通过示例代码帮助读者更好地理解Spring提供的各种Bean生命周期回调方法。
在Spring中,Bean的作用域决定了容器如何新建Bean实例的规则。Spring提供了几种作用域:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
@Configuration
public class BeanScopeConfig {
@Bean
@Scope("singleton")
public MyBean singletonBean() {
return new MyBean();
}
@Bean
@Scope("prototype")
public MyBean prototypeBean() {
return new MyBean();
}
}
Bean的生命周期指的是从Bean的初始化到销毁的整个过程。在这个过程中,Spring容器提供了多个扩展点,允许在Bean的创建和销毁过程中加入自定义逻辑。
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class MyLifecycleBean implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
// 初始化逻辑
System.out.println("MyLifecycleBean is initialized.");
}
@Override
public void destroy() throws Exception {
// 销毁逻辑
System.out.println("MyLifecycleBean is destroyed.");
}
}
通过实现InitializingBean
和DisposableBean
接口,我们可以在Bean的生命周期的特定时间点执行自定义逻辑。
在Spring框架中,Bean是构建应用程序的基石。它们不仅承载着数据和行为,还通过依赖关系与其他Bean相互作用。正确地管理Bean的属性和依赖关系,是实现高效、可维护Spring应用的关键。本篇博客将带你深入理解Bean的属性和依赖关系,并掌握Spring提供的属性配置和自动装配方式。
Bean的属性指的是Bean中的字段,这些字段可以通过XML配置、注解或JavaConfig来配置。
<bean id="exampleBean" class="com.example.ExampleBean">
<property name="beanProperty" value="Some Value"/>
</bean>
@Component
public class ExampleBean {
@Value("${some.value}")
private String beanProperty;
}
Bean的依赖关系指的是一个Bean依赖于另一个Bean来完成其操作。例如,一个服务类(Service)可能依赖于一个数据访问对象(DAO)。
<bean id="myDao" class="com.example.MyDao"/>
<bean id="myService" class="com.example.MyService">
<property name="myDao" ref="myDao"/>
</bean>
@Service
public class MyService {
private final MyDao myDao;
@Autowired
public MyService(MyDao myDao) {
this.myDao = myDao;
}
}
Spring提供了多种方式来配置Bean的属性,其中最常用的是@Value
注解。
@Value
注解@Value
注解可以用来注入普通属性、系统属性、环境变量等。
@Component
public class ExampleBean {
@Value("${app.name:defaultAppName}")
private String appName;
}
Spring的自动装配功能可以自动满足Bean之间的依赖,减少配置的工作量。最常用的自动装配注解是@Autowired
。
@Autowired
进行自动装配Spring会在容器中查找匹配类型的Bean,并注入到被@Autowired
标注的字段、构造器或方法中。
@Service
public class MyService {
private final MyDao myDao;
@Autowired
public MyService(MyDao myDao) {
this.myDao = myDao; // 自动装配
}
}
对于更复杂的自动装配场景,Spring提供了@Qualifier
和@Primary
注解来进一步控制自动装配的行为。
@Qualifier
指定具体的Bean当有多个同类型的Bean可供选择时,@Qualifier
注解可以用来指定具体要装配的Bean。
@Autowired
@Qualifier("specificDao")
private MyDao myDao;
@Primary
指定首选的Bean通过在Bean定义上使用@Primary
注解,可以指定当存在多个同类型Bean时,默认选择哪一个。
@Component
@Primary
public class PrimaryDao implements MyDao {
// 实现细节
}
在Spring框架中,BeanPostProcessor
和FactoryBean
是两个非常重要的接口,它们在Bean的生命周期管理和创建过程中扮演着关键角色。虽然它们的功能看似相近,但实际上各自的作用和应用场景大相径庭。
BeanPostProcessor
允许开发者插手Bean的初始化过程,在Bean的初始化前后执行一些自定义逻辑。
postProcessBeforeInitialization(Object bean, String beanName)
: 在任何Bean初始化回调方法(如InitializingBean
的afterPropertiesSet
或自定义的init方法)之前调用。postProcessAfterInitialization(Object bean, String beanName)
: 在所有Bean初始化回调之后调用。import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
// 在初始化之前执行的逻辑
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
// 在初始化之后执行的逻辑
return bean;
}
}
与BeanPostProcessor
不同,FactoryBean
是用于生成其他Bean实例的特殊Bean。当配置的Bean实现了FactoryBean
接口时,它将返回getObject()
方法所返回的对象,而不是FactoryBean本身。
T getObject()
: 返回由FactoryBean创建的Bean实例。Class<?> getObjectType()
: 返回FactoryBean创建的Bean类型。boolean isSingleton()
: 表明由FactoryBean创建的Bean是否为单例。FactoryBean
封装这些逻辑。import org.springframework.beans.factory.FactoryBean;
public class MyFactoryBean implements FactoryBean<MyBean> {
@Override
public MyBean getObject() throws Exception {
// 返回需要创建的Bean实例
return new MyBean();
}
@Override
public Class<?> getObjectType() {
return MyBean.class;
}
@Override
public boolean isSingleton() {
// 控制该Bean是否为单例
return true;
}
}
虽然BeanPostProcessor
和FactoryBean
都可以影响Spring容器中Bean的创建,但它们的主要区别在于:
BeanPostProcessor
是用于修改或包装已经存在的Bean实例的。FactoryBean
是用于创建新的Bean实例的。Spring Boot,作为现代Java开发中的一颗明星,以其“约定大于配置”的理念,极大地简化了Spring应用的开发、部署和运维。它不仅继承了Spring框架强大的依赖注入和面向切面编程的特性,还在此基础上提供了自动配置等功能,使得开发者可以更加专注于业务逻辑。本篇博客将带你深入理解Spring Boot的设计理念和主要特点,以及它在Bean管理和自动配置方面的实现原理。
Spring Boot遵循“约定大于配置”的原则,旨在减少项目搭建的复杂性和开发时的配置要求。它通过合理的默认配置,帮助开发者快速启动和开发Spring应用程序。
Spring Boot利用Spring框架的依赖注入(DI)特性来管理Bean。开发者可以通过注解如@Component
、@Service
、@Repository
等来声明Bean,并通过@Autowired
或构造器注入依赖。
@Service
public class MyService {
// 业务逻辑
}
@RestController
public class MyController {
private final MyService myService;
@Autowired
public MyController(MyService myService) {
this.myService = myService; // 自动装配
}
}
Spring Boot自动配置的魔法背后是@EnableAutoConfiguration
注解,这个注解通过@Import
引入了AutoConfigurationImportSelector
类,该类负责读取META-INF/spring.factories
文件中的配置,根据条件选择性地应用配置。
假设我们有一个自动配置类MyAutoConfiguration
,当classpath中存在某个特定类时,这个配置类就会被应用:
@Configuration
@ConditionalOnClass(SomeClass.class)
public class MyAutoConfiguration {
@Bean
public SomeBean someBean() {
return new SomeBean();
}
}
在resources/META-INF/spring.factories
文件中,我们声明这个自动配置类:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.example.MyAutoConfiguration
当Spring Boot应用启动时,如果classpath中存在SomeClass
,那么SomeBean
就会被自动配置。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有