讲一讲spring启动流程
时间: 2023-03-31 15:03:34 浏览: 132
好的,Spring 启动流程可以分为以下几个步骤:
1. 加载配置文件:Spring 启动时会读取配置文件,包括 XML 配置文件、Java 配置类等。
2. 创建 IOC 容器:Spring 会根据配置文件中的信息创建 IOC 容器,也就是 ApplicationContext。
3. 实例化 Bean:Spring 会根据配置文件中的信息,实例化 Bean,并将其放入 IOC 容器中。
4. 注入依赖:Spring 会根据配置文件中的信息,将 Bean 之间的依赖关系注入到对应的 Bean 中。
5. 调用初始化方法:Spring 会调用 Bean 中的初始化方法,例如 init-method。
6. 应用程序使用 Bean:Spring 启动完成后,应用程序可以通过 IOC 容器获取 Bean 并使用。
以上就是 Spring 启动流程的主要步骤。
相关问题
讲一讲Spring Ioc的底层原理 并手写一套
Spring Ioc的底层原理是基于反射和依赖注入实现的。在Spring容器启动时,会扫描所有的类,找到其中被注解为@Component、@Service、@Controller、@Repository等的类,并将其实例化为Bean对象,同时将其放入Bean工厂中进行管理。在Bean实例化的过程中,Spring使用反射机制调用构造方法或工厂方法来创建对象,并通过setter或构造方法注入依赖的其他Bean对象。这样,通过Ioc容器的管理,实现了对象之间的解耦和灵活性。
手写一套简单的Spring Ioc框架:
1. 定义注解@ComponentScan用于扫描指定包下的所有类,将被注解为@Component、@Service、@Controller、@Repository等的类实例化为Bean对象,并将其放入Bean工厂中进行管理。
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentScan {
String[] basePackages();
}
```
2. 定义注解@Component用于标注需要实例化为Bean对象的类。
```java
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Component {
String value() default "";
}
```
3. 定义Bean工厂类,存储所有的Bean对象。
```java
public class BeanFactory {
private Map<String, Object> beans = new ConcurrentHashMap<>();
public Object getBean(String name) {
return beans.get(name);
}
public void addBean(String name, Object bean) {
beans.put(name, bean);
}
}
```
4. 定义Bean扫描器,扫描指定包下的所有类,并将被注解为@Component、@Service、@Controller、@Repository等的类实例化为Bean对象,并将其放入Bean工厂中进行管理。
```java
public class BeanScanner {
private BeanFactory beanFactory;
public BeanScanner(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void scan(String... basePackages) {
for (String basePackage : basePackages) {
String path = basePackage.replaceAll("\\.", "/");
File file = new File(this.getClass().getResource("/" + path).getFile());
if (!file.exists()) {
continue;
}
if (file.isDirectory()) {
for (File subFile : file.listFiles()) {
scan(basePackage + "." + subFile.getName().replaceAll(".class", ""));
}
} else {
String className = basePackage + "." + file.getName().replaceAll(".class", "");
try {
Class<?> clazz = Class.forName(className);
if (clazz.isAnnotationPresent(Component.class)) {
Object bean = clazz.getDeclaredConstructor().newInstance();
beanFactory.addBean(clazz.getName(), bean);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
```
5. 定义注解@Autowired用于依赖注入。
```java
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Autowired {
}
```
6. 定义Bean注入器,通过反射机制注入依赖的Bean对象。
```java
public class BeanInjector {
private BeanFactory beanFactory;
public BeanInjector(BeanFactory beanFactory) {
this.beanFactory = beanFactory;
}
public void inject() {
for (Object bean : beanFactory.beans.values()) {
Field[] fields = bean.getClass().getDeclaredFields();
for (Field field : fields) {
if (field.isAnnotationPresent(Autowired.class)) {
try {
field.setAccessible(true);
Object dependencyBean = beanFactory.getBean(field.getType().getName());
field.set(bean, dependencyBean);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
}
}
```
7. 定义Spring Ioc框架的入口类,启动容器,并扫描指定包下的所有类,实例化为Bean对象,并将其放入Bean工厂中进行管理,最后注入依赖的Bean对象。
```java
public class SpringIoc {
public static void run(Class<?> clazz, String[] args) {
BeanFactory beanFactory = new BeanFactory();
BeanScanner beanScanner = new BeanScanner(beanFactory);
ComponentScan componentScan = clazz.getDeclaredAnnotation(ComponentScan.class);
beanScanner.scan(componentScan.basePackages());
BeanInjector beanInjector = new BeanInjector(beanFactory);
beanInjector.inject();
}
}
```
使用示例:
1. 定义两个类,一个依赖另一个。
```java
@Component
public class UserService {
public void sayHello() {
System.out.println("Hello, World!");
}
}
@Component
public class UserController {
@Autowired
private UserService userService;
public void hello() {
userService.sayHello();
}
}
```
2. 定义启动类,指定需要扫描的包,启动Spring Ioc容器。
```java
@ComponentScan(basePackages = "com.example")
public class Application {
public static void main(String[] args) {
SpringIoc.run(Application.class, args);
UserController userController = (UserController) BeanFactory.getBean("com.example.UserController");
userController.hello();
}
}
```
输出结果:
```
Hello, World!
```
讲出完整详细的spring IOC 流程
Spring IOC(Inversion of Control)是一种设计模式,它通过将对象的创建和依赖关系的管理交给容器来实现。下面是Spring IOC的详细流程:
1. 配置文件加载:Spring IOC的配置文件通常是XML格式的,它包含了应用程序中所有需要管理的对象的定义和依赖关系。当应用程序启动时,Spring IOC容器会读取这个配置文件。
2. Bean的实例化:Spring IOC容器会根据配置文件中的定义,实例化所有需要管理的Bean对象。这些Bean对象通常是Java类的实例,但也可以是其他类型的对象。
3. Bean的依赖注入:在实例化Bean对象之后,Spring IOC容器会自动将它们之间的依赖关系注入到Bean对象中。这些依赖关系通常是其他Bean对象的引用,也可以是基本类型的值或者集合类型的对象。
4. Bean的初始化:在依赖注入完成之后,Spring IOC容器会调用Bean对象的初始化方法。这些方法通常用来完成一些必要的初始化工作,例如建立数据库连接、加载配置文件等。
5. Bean的使用:在初始化完成之后,Spring IOC容器会将所有的Bean对象交给应用程序使用。应用程序可以通过容器提供的接口来获取需要的Bean对象,并调用它们的方法完成业务逻辑。
6. Bean的销毁:当应用程序关闭时,Spring IOC容器会自动销毁所有的Bean对象。在销毁之前,容器会调用Bean对象的销毁方法,完成一些必要的清理工作,例如关闭数据库连接、释放资源等。
以上就是Spring IOC的详细流程。通过使用Spring IOC,我们可以将对象的创建和依赖关系的管理交给容器来完成,从而使应用程序更加灵活、可扩展和易于维护。
阅读全文