Spring相关面试知识点
Spring自动装配(Spring实现IOC的一种方式)
基于xml方式实现的自动装配
Spring容器自动装配相互协作的Bean,将一个Bean注入其他Bean的Property中。
元素的自动装配属性值:
-
no 默认 不自动装配,Bean依赖需要使用ref元素自己手动装配。
-
byName 根据Property的name自动装配,一个Bean的name和另一个Bean的Property的name相等,则自动装配这个Bean到Property中
-
byType根据Property的数据类型(Type)自动装配,如果一个Bean的数据类型兼容另一个Bean中Property的数据类型,则自动装配
-
constructor:类似于byType,根据构造方法参数的数据类型,进行byType模式的自动装配
自动装配的优缺点:
优点: 自动装配只需要较少的代码就可以实现依赖注入
缺点:不能装配简单数据类型
其他注意点
Spring默认不使用注解自动装配,在配置文件中加入context:annotation-config/启用注解,
使用component-scan base-package 指定需要使用注解的包
基于注解实现的自动装配
常用注解:
-
bean的定义:
@Component @Controller @Service @Repository
-
bean的注入
@Autowired @Qualifier @Resource
-
bean属性的赋值
@Value @ConfigurationProperties
自动装配与依赖注入
依赖注入
在对象创建时将其依赖的资源(如其他对象、数据源)注入到对象中的一种设计模式
通过容器来管理Bean之间的依赖关系,将依赖的对象提供给被依赖的对象,使得对象之间解耦并易于测试和维护
可以通过构造函数注入、Setter方法注入、接口注入和注解注入等方式实现
自动装配
一种依赖注入的方式,Spring自动根据特定的规则将Bean注入到需要它们的目标Bean中
Spring自动装配允许开发人员不需要显示指定每个Bean之间的依赖关系,而是由Spring根据一定的规则自动完成依赖注入
自动装配可以通过@Autowired注解、@Resource注解、@Inject注解实现
以下是几种常见的依赖注入方式在 Spring 中的具体例子:
1. 构造函数注入
public class UserService { private final UserRepository userRepository; public UserService(UserRepository userRepository) { this.userRepository = userRepository; } }
2. Setter 方法注入
public class UserService { private UserRepository userRepository; public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } }
3. 接口注入
public interface UserRepository { // 定义操作接口 } public class UserRepositoryImpl implements UserRepository { // 实现接口 } public class UserService { private UserRepository userRepository; public void setUserRepository(UserRepository userRepository) { this.userRepository = userRepository; } }
4. 注解注入(@Autowired)
@Service public class UserService { @Autowired private UserRepository userRepository; }
5. 注解注入(@Resource)
@Service public class UserService { @Resource private UserRepository userRepository; }
6. 注解注入(@Inject)
@Service public class UserService { @Inject private UserRepository userRepository; }
如何在Spring项目中得到自己需要的Bean
在 Spring 中,在项目中获取具体的 Bean 可以通过以下几种方式:
-
通过 @Autowired 注解进行自动装配:在需要使用该 Bean 的地方,可以使用 @Autowired 注解将 Bean 注入进来。
@Autowired private YourBeanClassName yourBeanInstance;
-
通过 ApplicationContext 获取:可以通过 ApplicationContext.getBean() 方法直接从 Spring 容器中获取 Bean。
YourBeanClassName yourBeanInstance = context.getBean(YourBeanClassName.class);
-
通过 BeanFactory 获取:可以通过 BeanFactory.getBean() 方法从 BeanFactory 中获取 Bean。
YourBeanClassName yourBeanInstance = beanFactory.getBean(YourBeanClassName.class);
-
通过 @Resource 注解:@Resource 注解可以用来注入对象、查找对象。直接将目标 Bean 注入到需要的地方。
@Resource private YourBeanClassName yourBeanInstance;
-
通过 @Inject 注解:@Inject 是 Java 依赖注入规范的一部分,与 @Autowired 类似用法,可以直接注入 Bean。
@Inject private YourBeanClassName yourBeanInstance;
-
使用 BeanDefinitionRegistryPostProcessor:实现 BeanDefinitionRegistryPostProcessor 接口,在 postProcessBeanDefinitionRegistry() 方法中可以获取到所有注册的 BeanDefinition 信息。
@Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { BeanDefinition beanDefinition = registry.getBeanDefinition("beanName"); }
在@Configuration配置类注入Bean
在一个使用 @Configuration
注解声明的配置类中,如果你想要注入一个 Bean,一种常见的做法是通过方法注入其他 Bean。以下是在 @Configuration
类中注入 Bean 的示例:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AppConfig { @Bean public YourBeanClass yourBean() { return new YourBeanClass(); } @Bean public AnotherBeanClass anotherBean(YourBeanClass yourBean) { return new AnotherBeanClass(yourBean); } }
在这个示例中,AppConfig
配置类中声明了两个 Bean 方法:yourBean()
和 anotherBean()
。anotherBean()
方法中注入了 yourBean()
方法返回的 Bean,Spring 容器会负责解析依赖关系并确保正确实例化和管理这些 Bean。
SpringBean的实例化和初始化
-
实例化(Instantiation):
-
实例化是指在容器启动或者根据需要创建新Bean时,从Bean定义中生成Bean实例的过程。
-
在实例化阶段,Spring容器根据Bean定义创建Bean的实例对象。这可以是通过构造函数实例化,也可以是通过工厂方法或其他方式。
-
实例化后,Bean对象的物理实例存在于内存中,但尚未完成所有的初始化工作。
-
-
初始化(Initialization):
-
初始化是指Bean实例创建后,容器会调用特定的方法来对Bean进行一些额外的操作,以完成Bean的配置、依赖注入和准备工作。
-
在初始化阶段,Spring容器会执行一系列生命周期回调方法,如调用
@PostConstruct
注解的方法、实现InitializingBean
接口的afterPropertiesSet()
方法等。 -
初始化阶段通常包括属性注入、依赖处理和其他自定义操作,确保Bean对象处于可用的状态。
-
Spring的初始化方法
在Spring框架中,默认的Bean初始化方法是使用接口回调,即Bean实现InitializingBean
接口,并在实现类中重写afterPropertiesSet()
方法来进行初始化操作。当Bean被实例化后,Spring容器会自动调用实现了InitializingBean
接口的Bean的afterPropertiesSet()
方法来完成初始化工作。这种方式是Spring框架提供的默认初始化方法,确保在Bean实例化后执行所需的初始化操作。
SpringMVC工作流程
客户端请求被DispatcherServlet接收 根据HandlerMapping映射到Handler 生成Handler和HandlerInterceptor Handler和HandlerInterceptor以HandlerExecutionChain的形式一并返回给DispatcherServlet DispatcherServlet通过HandlerAdapter调用Handler的方法完成业务逻辑处理 返回一个ModelAndView对象给DispatcherServlet DispatcherServlet把获取的ModelAndView对象传给ViewResolver视图解析器,把逻辑视图解析成物理视图 ViewResolver返回一个View进行视图渲染(把模型填充到视图中) DispatcherServlet把渲染后的视图响应给客户端
SpringBoot应用程序中的一些重要注解
@SpringBootApplication:用于SpringBoot主启动类
包含注解:
@Configuration:标志该类为配置类,定义为Bean
@EnableAutoConfiguration:实现SpringBoot自动装配的注解
@ComponentScan:SpringBean组件扫描