Spring 简介

1. Spring简介

1.1 Spring 核心设计思想

1.1.1 Spring 是什么?

  • Spring 是包含了众多⼯具⽅法的 IoC 容器。
  • Spring 指的是 Spring Framework(Spring 框架),它是⼀个开源框架,Spring ⽀持⼴泛的应⽤场景,它可以让 Java 企业级的应⽤程序开发起来更简单。
1.1.1.1 什么是IoC容器?
  • 容器是⽤来容纳某种物品的装置。
  • IoC = Inversion of Control 翻译成中⽂是"控制反转"的意思,控制权发⽣的反转,不再是上级对象创建并控制下级对象了,⽽是下级对象把注⼊将当前对象中,下级的控制权不再由上级类控制了,这样即使下级类发⽣任何改变,当前类都是不受影响的,这就是 IoC 的实现思想。
  • Spring具备两个核心功能:将对象存⼊到容器,从容器中取出对象。对象的创建和销毁的权利都交给 Spring 来管理了,它本身⼜具备了存储对象和获取对象的能⼒。
1.1.1.2 DI 概念说明

DI 是 Dependency Injection 的缩写,翻译成中⽂是"依赖注⼊"的意思。依赖注⼊就是由 IoC 容器在运⾏期间,动态地将某种依赖关系注⼊到对象之中。所以,依赖注⼊(DI)和控制反转(IoC)是从不同的⻆度的描述的同⼀件事情,就是指通过引⼊ IoC 容器,利⽤依赖关系注⼊的⽅式,实现对象之间的解耦,IoC 是"⽬标"也是⼀种思想,⽽⽬标和思想只是⼀种指导原则,最终还是要有可⾏的落地⽅案,⽽ DI就属于具体的实现。

1.1.1.3 IoC容器和普通程序开发的区别
  • 将对象存储在 IoC 容器相当于将以后可能⽤的所有⼯具制作好都放到仓库中,需要的时候直接取就⾏了,⽤完再把它放回到仓库。
  • new 对象的⽅式相当于,每次需要工具了才现做,用完扔掉了也不会保存,下次再用的时候还得重新做。

1.2 Spring 创建和使用

1.2.1 创建 Spring 项目

使⽤ Maven ⽅式来创建⼀个 Spring 项⽬,创建 Spring 项⽬和 Servlet 类似。

  1. 创建⼀个 Maven 项⽬

    然后跳转到了这个页面:
  2. 添加 Spring 框架⽀持
    在项⽬的 pom.xml 中添加 Spring 框架的⽀持spring-context(spring 上下⽂)和spring-beans(管理对 象的模块),xml 配置如下:
java 复制代码
<dependencies>
   <dependency> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-context</artifactId> 
        <version>5.2.3.RELEASE</version> 
    </dependency>

    <dependency> 
        <groupId>org.springframework</groupId> 
        <artifactId>spring-beans</artifactId> 
        <version>5.2.3.RELEASE</version> 
    </dependency>
</dependencies>
  1. 添加启动类
    最后在创建好的项⽬ java ⽂件夹下创建⼀个启动类,包含 main ⽅法即可:
java 复制代码
public class App {
    public static void main(String[] args) {

    }
}

到此为止,一个spring项目就搭建好了。

1.2.2 存储 Bean 对象

Bean 就是 Java 语⾔中的⼀个普通对象,例如:

java 复制代码
public class User {
   public String sayHi(String name) { 
       return name + " hello!";
   }
}
  1. 创建 Bean
java 复制代码
public class User {
    public String sayHi(String name) { 
        return name + " hello!";
    }
}
  1. 将 Bean 注册到容器
    <<1>>在创建好的项⽬中添加 Spring 配置⽂件 spring-config.xml,将此⽂件放到 resources 的根⽬录下, 如下图所示:

    <<2>> spring-config.xml 配置⽂件的固定格式为以下内容,复制粘贴即可
xml 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

<<3>> 将 User 对象注册到 Spring 中就可以,在 标签中添加配置 ,格式如下:

xml 复制代码
<beans>
  <bean id="user" class="com.bit.User"></bean>
</beans>

1.2.3 获取 Bean 对象

  1. 创建 Spring 上下⽂对象
    <<1>>使⽤ ApplicationContext
java 复制代码
ApplicationContext context = new ClassPathXmlApplicationContext("spring-con fig.xml");

<<2>>使⽤ BeanFactory

java 复制代码
BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource("spring-config.xml"));

ApplicationContext VS BeanFactory

  • 继承关系和功能⽅⾯:Spring 容器有两个顶级的接⼝:BeanFactory 和 ApplicationContext。其中 BeanFactory 提供了基础的访问容器的能⼒,⽽ ApplicationContext 属于 BeanFactory 的⼦类,它除了继承了 BeanFactory 的所有功能之外,它还拥有独特的特性, 还添加了对国际化⽀持、资源访问⽀持、以及事件传播等⽅⾯的⽀持。
  • 性能⽅⾯:ApplicationContext 是⼀次性加载并初始化所有的 Bean 对象,⽽ BeanFactory 是需要那个才去加载那个,因此更加轻量。
    <<3>>使用ClassPathXmlApplicationContext
    ClassPathXmlApplicationContext 属于 ApplicationContext 的⼦类,拥有 ApplicationContext 的所有功能,通过 xml 的配置来获取所有的 Bean 容器。
  1. 获取指定的 Bean 对象
java 复制代码
// 1.得到 Spring 上下⽂对象
ApplicationContext context = new ClassPathXmlApplicationContext("spring-con fig.xml");
// 2.加载某个 bean
User user = (User) context.getBean("user");

Bean 的 Id 要⼀⼀对应,如下图所示:

getBean ⽅法的更多⽤法

  • 根据类型获取 Bean:
java 复制代码
UserController user = context.getBean(UserController.class);
  • 名称 + 类型获取 Bean:
java 复制代码
UserController user = context.getBean("user", UserController.class);

当有⼀个类型被重复注册到 spring-config.xml 中时,只能使⽤根据名称获取了,⽐如以 下场景就会导致程序报错:

1.2.4 使用 Bean

java 复制代码
public class App {
    public static void main(String[] args) {
        // 1.得到 Spring 上下⽂对象
        ApplicationContext context =
                new ClassPathXmlApplicationContext("spring-config.xml"); 
        // 2.加载某个 bean
        User user = (User) context.getBean("user");
        // 3.调⽤相应的⽅法
        System.out.println(user.sayHi("Java"));
    }
}

1.2.4 使用注解读取和存储对象

  1. 配置扫描路径

配置⼀下存储对象的扫描包路径,只有在被配置的包下且添加了注解的类才能被正确的识别并保存到 Spring 中。

在 spring-config.xml 添加如下配置:

java 复制代码
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:content="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
 
 <content:component-scan base-package="com.bit.service"></content:component-scan>
 
</beans>
  1. 添加注解存储 Bean 对象
    将对象存储在 Spring 中,有两种注解类型可以实现:
  • 类注解:@Controller(表示业务逻辑层)、@Service(服务层)、@Repository(持久层)、@Component、@Configuration(配置层)。
  • ⽅法注解:@Bean
    类注解是添加到某个类上的,⽅法注解是放到某个⽅法上的。

Bean 命名规则:

通常 bean 使⽤的都是标准的⼤驼峰命名,读取的时候⾸字⺟⼩写:

当⾸字⺟和第⼆个字⺟都是⼤写时,不能正常读取到 bean :

Spring中 bean 存储时⽣成的命名规则:

<1> 在 Idea 中使⽤搜索关键字"beanName"可以看到以下内容:

它使⽤的是 JDK Introspector 中的 decapitalize ⽅法,源码如下:

java 复制代码
public static String decapitalize(String name) {
   if (name == null || name.length() == 0) {
       return name;
   }
   // 如果第⼀个字⺟和第⼆个字⺟都为⼤写的情况,是把 bean 的⾸字⺟也⼤写存储了 
   if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) && 
       Character.isUpperCase(name.charAt(0))){
       return name;
   }
	// 否则就将⾸字⺟⼩写
   char chars[] = name.toCharArray();
   chars[0] = Character.toLowerCase(chars[0]);
   return new String(chars);
}

所以对于上⾯报错的代码,只要改为以下代码就可以正常运⾏了:

类注解使用示例:

  • @Controller(控制器存储)
    使⽤ @Controller 存储 bean:
java 复制代码
@Controller // 将对象存储到 Spring 中
public class UserController {
	public void sayHi(String name) {
		System.out.println("Hi," + name);
	}
}

先使⽤之前读取对象的⽅式读取上⾯的 UserController 对象:

java 复制代码
public class Application {
	public static void main(String[] args) {
		// 1.得到 spring 上下⽂
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		// 2.得到 bean
		UserController userController = (UserController) context.getBean("userController");
		// 3.调⽤ bean ⽅法
		userController.sayHi("Bit");
	}
}
  • @Service(服务存储)
    使⽤ @Service 存储 bean
java 复制代码
@Service
public class UserService {
	 public void sayHi(String name) {
		System.out.println("Hi," + name);
	 }
}

读取 bean

java 复制代码
class App {
	public static void main(String[] args) {
		 // 1.得到 spring 上下⽂
		 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		 // 2.得到 bean
		 UserService userService = (UserService) context.getBean("userService");
		 // 3.调⽤ bean ⽅法
		 userService.sayHi("Bit");
	}
}
  • @Repository(仓库存储)
    使⽤ @Repository 存储 bean
java 复制代码
@Repository
public class UserRepository {
	 public void sayHi(String name) {
		System.out.println("Hi," + name);
	 }
}

读取 bean

java 复制代码
class App {
	public static void main(String[] args) {
		// 1.得到 spring 上下⽂
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		// 2.得到某个 bean
		UserRepository userRepository = (UserRepository) context.getBean("userRepository");
		// 3.调⽤ bean ⽅法
		userRepository.sayHi("Bit");
	}
}
  • @Component(组件存储)
    使⽤ @Component 存储 bean
java 复制代码
@Component
public class UserComponent {
	public void sayHi(String name) {
		System.out.println("Hi," + name);
	}
}

读取 bean

java 复制代码
class App {
	public static void main(String[] args) {
		// 1.得到 spring 上下⽂
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		// 2.得到某个 bean
		UserComponent userComponent = (UserComponent) context.getBean("userComponent");
	 	// 3.调⽤ bean ⽅法
		userComponent.sayHi("Bit");
	 }
}
  • @Configuration(配置存储)
java 复制代码
@Configuration
public class UserConfiguration {
	public void sayHi(String name) {
		System.out.println("Hi," + name);
	}
}

读取 bean

java 复制代码
class App {
	public static void main(String[] args) {
		// 1.得到 spring 上下⽂
		ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
		// 2.得到某个 bean
		UserConfiguration userConfiguration = (UserConfiguration) context.getBean("userConfiguration");
		// 3.调⽤ bean ⽅法
		userConfiguration.sayHi("Bit");
	 }
}

为什么有这么多功能一样的注解:

它们的功能都是一样的,让程序员看到类注解之后,就能直接了解当前类的⽤途。

程序的⼯程分层,调⽤流程:

查看 @Controller / @Service / @Repository / @Configuration 等注解的源码发现,这些注解⾥⾯都有⼀个注解 @Component,说明它们本身就是属于 @Component 的"⼦类"。

⽅法注解@Bean 使用示例:

⽅法注解要配合类注解使⽤

在 Spring 框架的设计中,⽅法注解 @Bean 要配合类注解才能将对象正常的存储到 Spring 容器中

  • 使用@Bean存储 bean
java 复制代码
@Component
public class Users {

   @Bean
   public User user1() { 
       User user = new User(); 
       user.setId(1); 
       user.setName("Java"); 
       return user;
   }
}

读取bean

java 复制代码
public class Application {
   public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); 
       User user = (User) context.getBean("user1"); 
       System.out.println(user.toString());
   }
}
  • 重命名 Bean
    可以通过设置 name 属性给 Bean 对象进⾏重命名。重
java 复制代码
@Component
public class Users { 
   @Bean(name = {"u1"}) 
   public User user1() { 
       User user = new User(); 
       user.setId(1); 
       user.setName("Java"); 
       return user;
   }
}

命名的 name 其实是⼀个数组,⼀个 bean 可以有多个名字。

java 复制代码
@Bean(name = {"u1", "us1"}) public User user1() { 
 User user = new User(); 
 user.setId(1); 
 user.setName("Java"); 
 return user;
}

name={} 可以省略

java 复制代码
@Bean({"u1", "us1"})
public User user1() { 
  User user = new User(); 
  user.setId(1); 
  user.setName("Java"); 
  return user;
}

此时使⽤ u1/us1 就可以获取到 User 对象了

java 复制代码
class App {
   public static void main(String[] args) {
       // 1.得到 spring 上下⽂
       ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); 
       // 2.得到某个 bean
       User user = (User) context.getBean("u1");
       // 3.调⽤ bean ⽅法
       System.out.println(user);
   }
}
  1. 对象装配

获取 bean 对象也叫做对象装配,是把对象取出来放到某个类中,有时候也叫对象注⼊。

<1> 属性注⼊

属性注⼊使⽤ @Autowired 实现。

属性注⼊的优点是简洁,使⽤⽅便;缺点是只能⽤于 IoC 容器,如果是⾮ IoC 容器不可⽤,并且只 有在使⽤的时候才会出现 NPE(空指针异常)。

示例:

Service 类的实现代码如下:

java 复制代码
import org.springframework.stereotype.Service;

@Service
public class UserService {

   /**
    * 根据 ID 获取⽤户数据
    *
    * @param id
   * @return
    */
   public User getUser(Integer id) { 
       // 伪代码,不连接数据库 
       User user = new User(); 
       user.setId(id); 
       user.setName("Java-" + id); 
       return user;
   }
}
  • Controller 类的实现代码如下:
java 复制代码
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller;

@Controller
public class UserController {

   // 注⼊⽅法1:属性注⼊ 
   @Autowired
   private UserService userService;

   public User getUser(Integer id) { 
       return userService.getUser(id); 
   }
}

核⼼实现:

获取 Controller 中的 getUser ⽅法:

java 复制代码
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class UserControllerTest {
   public static void main(String[] args) {
       ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); 
       UserController userController = context.getBean(UserController.cla ss);
   		System.out.println(userController.getUser(1).toString());
   }
}

运行结果:

<2>构造⽅法注⼊

构造⽅法注⼊是在类的构造⽅法中实现注⼊。

构造⽅法注⼊是 Spring 推荐的注⼊⽅式,它的缺点是如果有多个注⼊会显得⽐较臃肿,但出现这 种情况应该考虑⼀下当前类是否符合程序的单⼀职责的设计模式,优点是通⽤性,在使⽤之前⼀定能把保证注⼊的类不为空。

示例:

java 复制代码
@Controller
public class UserController2 {

   // 注⼊⽅法2:构造⽅法注⼊ 
   private UserService userService;     // 创建userService引用

   @Autowired 
   public UserController2(UserService userService) {   // 注入并通过构造方法让上面的引用指向注入进来的这个对象
       this.userService = userService;
  }

   public User getUser(Integer id) { 
       return userService.getUser(id); 
   }
}

<<1>> 如果只有⼀个构造⽅法,那么 @Autowired 注解可以省略

<<2>>如果类中有多个构造⽅法,那么需要添加上 @Autowired 来明确指定到底使⽤哪个构造⽅法,否则 程序会报错

<3> Setter 注⼊

Setter 注⼊和 构造方法注入 实现类似,只不过在设置 set ⽅法的时候需要加上 @Autowired 注解。

Setter ⽅式是 Spring 前期版本推荐的注⼊⽅式,但通⽤性不如构造⽅法,所有 Spring 现版本已 经推荐使⽤构造⽅法注⼊的⽅式来进⾏类注⼊了。

示例:

java 复制代码
@Controller
public class UserController3 {

   // 注⼊⽅法3:Setter注⼊ 
   private UserService userService;

   @Autowired
   public void setUserService(UserService userService) { 
       this.userService = userService;
   }

   public User getUser(Integer id) { 
       return userService.getUser(id); 
   }
}

<4> @Resource注入

@Autowired 和 @Resource 的区别:

  • @Autowired 来⾃于 Spring,⽽ @Resource 来⾃于 JDK 的注解
  • 相⽐于 @Autowired ,@Resource ⽀持更多的参数设置,例如 name 设置,根据名称获取 Bean。
  • @Autowired 可⽤于 Setter 注⼊、构造方法注⼊和 属性注⼊。⽽ @Resource 只能⽤于 Setter 注⼊和 属性注⼊ 不能⽤于构造函数注⼊。

<5>使用同⼀类型多个 Bean 报错处理,当出现以下多个 Bean,返回同⼀对象类型时程序会报错。

示例:

java 复制代码
@Component
public class Users {
    
   // 第一个bean
   @Bean
   public User user1() { 
       User user = new User(); 
       user.setId(1); 
       user.setName("Java"); 
       return user;
   }

   // 第二个bean
   @Bean
   public User user2() { 
       User user = new User(); 
       user.setId(2); 
       user.setName("MySQL"); 
       return user;
   }
}

在另⼀个类中获取 User 对象:

java 复制代码
@Controller
public class UserController4 {

   // 注⼊ 
   @Resource 
   private User user;

   public User getUser() { 
       return user;
   }
}

执⾏结果:

解决方法:

<<1>>使⽤ @Resource(name="XXX")来指定bean

java 复制代码
@Controller
class UserController4 { 
   // 注⼊
   @Resource(name = "user1") 
   private User user;

   public User getUser() { 
       return user;
   }
}

<2> 使⽤ @Qualifier来指定bean

java 复制代码
@Controller
public class UserController5 { 
    // 注⼊
    @Autowired 
    @Qualifier(value = "user2") 
    private User user;

    public User getUser() { 
        return user;
    }
}

2. Bean 详解

2.1 Bean的作用域

限定程序中变量的可⽤范围叫做作⽤域,或者说在源代码中定义变量的某个区域就叫做作⽤域。

Bean 的作⽤域是指 Bean 在 Spring 整个框架中的某种⾏为模式。

Bean 有 6 种作⽤域:singleton(单例作⽤域),prototype(原型作⽤域/多例作⽤域), request(请求作⽤域),session(回话作⽤域),application(全局作⽤域),websocket(HTTP WebSocket 作⽤域)。后 4 种状态是 Spring MVC 中的值,在普通的 Spring 项⽬中只有前两种。

2.1.1 singleton

Spring默认选择该作⽤域,该作⽤域下的Bean在IoC容器中只存在⼀个实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired等注⼊)都是同⼀个对象。通常⽆状态的Bean(Bean对象的属性状态不需要更新)使⽤该作⽤域,单例可以很⼤程度上提⾼性能。

示例:

公共bean

java 复制代码
@Component
public class Users {
 	@Bean
 	public User user1() {
 		User user = new User();
 		user.setId(1);
 		user.setName("Java"); // 【重点:名称是 Java】
 		return user;
 	}
}

A ⽤户使⽤时,进⾏了修改操作:

java 复制代码
@Controller
public class BeanScopesController {
	 @Autowired
 	 private User user1;
	 public User getUser1() {
		 User user = user1;
		 System.out.println("Bean 原 Name:" + user.getName());
		 user.setName("悟空"); // 【重点:进⾏了修改操作】
		 return user;
	 }
}

B ⽤户再去使⽤公共 Bean :

java 复制代码
@Controller
public class BeanScopesController2 {
	 @Autowired
	 private User user1;
	 public User getUser1() {
		 User user = user1;
		 return user;
	 }
}

查看 A ⽤户和 B ⽤户公共 Bean 的值:

java 复制代码
public class BeanScopesTest {
 public static void main(String[] args) {
	 ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
 
	 BeanScopesController beanScopesController = context.getBean(BeanScopesController.class);
	 System.out.println("A 对象修改之后 Name:" + beanScopesController.getUser1().toString());
 
	 BeanScopesController2 beanScopesController2 = context.getBean(BeanScopesController2.class);
	 System.out.println("B 对象读取到的 Name:" + beanScopesController2.getUser1().toString());
 }
}

执⾏结果:

2.1.2 prototype

每次对该作⽤域下的Bean的请求都会创建新的实例:获取Bean(即通过applicationContext.getBean等⽅法获取)及装配Bean(即通过@Autowired注⼊)都是新的对象实例。通常有状态(Bean对象的属性状态需要更新)的Bean使⽤该作⽤域。

2.1.3 request

每次http请求会创建新的Bean实例,类似于prototype。用于⼀次http的请求和响应的共享Bean,限定SpringMVC中使⽤。

2.1.4 session

在⼀个http session中,定义⼀个Bean实例,用于用户回话的共享Bean,⽐如:记录⼀个⽤户的登陆信息。限定SpringMVC中使⽤。

2.1.5 application

在⼀个http servlet Context中,定义⼀个Bean实例,用于Web应⽤的上下⽂信息,⽐如:记录⼀个应⽤的共享信息。限定SpringMVC中使⽤。
application 是 Spring Web 中的作⽤域,作⽤于 Servlet 容器。singleton 是 Spring Core 的作⽤域,singleton 作⽤于 IoC 的容器。

2.1.6 websocket

在⼀个HTTP WebSocket的⽣命周期中,定义⼀个Bean实例,用于WebSocket的每次会话中,保存了⼀个Map结构的头信息,将⽤来包裹客户端消息头。第⼀次初始化后,直到WebSocket结束都是同⼀个Bean。限定Spring WebSocket中使⽤。

2.2 设置Bean的作用域

使⽤ @Scope 标签就可以⽤来声明 Bean 的作⽤域。

<1> 直接设置值:@Scope("prototype")

<2> 使⽤枚举设置:@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)

示例;

java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
@Component
public class Users {
	 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
	 @Bean(name = "u1")
	 public User user1() {
		 User user = new User();
		 user.setId(1);
		 user.setName("Java"); // 【重点:名称是 Java】
		 return user;
	 }
}

2.2 Bean的生命周期

2.2.1 Spring 执行流程

2.2.2 Bean 的执行流程

启动 Spring 容器 --> 实例化 Bean(分配内存空间,从⽆到有) --> Bean注册到Spring中(存操作) --> 将Bean装配到需要的类中(取操作)。

2.2.3 Bean的生命周期

⽣命周期指的是⼀个对象从诞⽣到销毁的整个⽣命过程,我们把这个过程就叫做⼀个对象的⽣命周期。

  1. 实例化 Bean(为 Bean 分配内存空间)
  2. 设置属性(Bean 注⼊和装配)
  3. Bean 初始化
    3.1 实现了各种 Aware 通知的⽅法,如 BeanNameAware、BeanFactoryAware ApplicationContextAware >的接⼝⽅法;
    3.2 执⾏ BeanPostProcessor 初始化前置⽅法;
    3.3 执⾏ @PostConstruct 初始化⽅法,依赖注⼊操作之后被执⾏;
    3.4 执⾏⾃⼰指定的 init-method ⽅法(如果有指定的话);
    3.5 执⾏ BeanPostProcessor 初始化后置⽅法。
  4. 使⽤ Bean
  5. 销毁 Bean。执行销毁容器的各种⽅法,如 @PreDestroy、DisposableBean 接⼝⽅法、destroy-method。
  • 实例化和初始化的区别:
    实例化和属性设置是 Java 级别的系统"事件",其操作过程不可⼈⼯⼲预和修改;⽽初始化是给开发者 提供的,可以在实例化之后,类加载完成之前进⾏⾃定义"事件"处理。
  • 如何理解Bean生命周期:
    Bean 的⽣命流程看似繁琐,但咱们可以以⽣活中的场景来理解它,⽐如我们现在需要买⼀栋房⼦,那么我们的流程是这样的:
  1. 先买房(实例化,从⽆到有);
  2. 装修(设置属性);
  3. 买家电,如洗⾐机、冰箱、电视、空调等([各种]初始化);
  4. ⼊住(使⽤ Bean);
  5. 卖出去(Bean 销毁)。
相关推荐
渣哥16 分钟前
原来 Java 里线程安全集合有这么多种
java
间彧24 分钟前
Spring Boot集成Spring Security完整指南
java
间彧1 小时前
Spring Secutiy基本原理及工作流程
java
Java水解2 小时前
JAVA经典面试题附答案(持续更新版)
java·后端·面试
洛小豆4 小时前
在Java中,Integer.parseInt和Integer.valueOf有什么区别
java·后端·面试
前端小张同学4 小时前
服务器上如何搭建jenkins 服务CI/CD😎😎
java·后端
ytadpole4 小时前
Spring Cloud Gateway:一次不规范 URL 引发的路由转发404问题排查
java·后端
华仔啊5 小时前
基于 RuoYi-Vue 轻松实现单用户登录功能,亲测有效
java·vue.js·后端
程序员鱼皮5 小时前
刚刚 Java 25 炸裂发布!让 Java 再次伟大
java·javascript·计算机·程序员·编程·开发·代码